C# Corner

.NET 4.5 TypeInfo Reflection

The .NET 4.5 Framework includes some changes to the typical reflection use cases. Most importantly, the Type object has been split into two separate classes: Type and TypeInfo. Find out how and when to use each.

The .NET 4.5 Framework includes some changes to the typical reflection use cases. Most importantly, the Type object has been split into two separate classes: Type and TypeInfo. A TypeInfo instance contains the definition for a Type, and a Type now contains only reference data. If you're using reflection from within a .NET 4.5 Desktop or Web application, the old API is still available alongside the new API methods. Today I'll focus on how to use some of the key features of these new APIs available within a Windows Store application.

Type and TypeInfo Overview
The Type class provides a shallow view of an object's structure; a TypeInfo object represents the full definition of an object, including its relationship to its parent and child classes, if any. Furthermore, the Type API has been updated to return generic IEnumerable collections rather than generic array collections. This change could allow for the lazy traversal of a complex assembly via a custom reflection context. Mainly, the change allows for Type metadata to be traversed more easily via LINQ. Windows Store applications may only access the new IEnumerable collections.

Type API Changes
Let's look at some of the metadata that may be retrieved through Type without using TypeInfo, then dive into some of the TypeInfo API. The Type API allows for the retrieval of information about a type available to its calling assembly. This means you can get basic metadata such as the name, namespace, full name, module and so on. This is accomplished through the same API as in .NET 4.0. For example, to get the full name and namespace of a Type, you could do the following:

Type stringType = typeof(string);
string fullName = stringType.FullName;
string stringNameSpace = stringType.Namespace;

TypeInfo API
As you can see, Type offers a basic view of the structure of a class. If you want to dive a bit deeper into the structure of a class, you can use the new TypeInfo API. The TypeInfo definition of a Type is retrieved via the GetTypeInfo() method upon the Type object. Take a Person class, for example, that contains first and last name properties, a Modified event and a Save method:

public class Person 
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public event EventHandler Modified;
    public void Save()
    {
        // save object to repository...
    }
}
Now, let's say you need to find out what properties, methods and events are defined on the Person class. This can be accomplished easily from a TypeInfo, via its DeclaredProperties, DeclaredMethods and DeclaredProperties:

TypeInfo personInfo = personType.GetTypeInfo();
IEnumerable<PropertyInfo> declaredProperties = personInfo.DeclaredProperties;
IEnumerable<MethodInfo> declaredMethods = personInfo.DeclaredMethods;
IEnumerable<EventInfo> declaredEvents = personInfo.DeclaredEvents;

Another common reflection task is to find all of the Types within an assembly. With the updated System.Reflection API, the Assembly class now returns a collection of TypeInfos rather than a Type array. For example, to get all the types defined in the running assembly, you can use the Assembly property from a retrieved TypeInfo definition. Then you'd access the DefinedTypes property on the Assembly instance:

Assembly myAssembly = this.GetType().GetTypeInfo().Assembly;
IEnumerable<TypeInfo> myTypes = myAssembly.DefinedTypes;

To get a better understanding of the new System.Reflection APIs, let's create a sample application that retrieves a list of all the defined types in the running assembly. When a Type is selected, its name, full name, declared properties, methods, and events are displayed.

Creating the Sample Application
To get started, create a new C# Windows Store application and add the Person class to the project, as shown earlier. Next, open up the MainPage.xaml file and add the XAML contained in Listing 1 as your root Grid element.

Now let's update the MainPage class to populate the list of defined types in the executing assembly. First, add a using statement for the System.Reflection namespace to the MainPage class. Then update the OnNavigatedTo method to retrieve the defined types for the application's assembly and bind it to the MyDefinedTypes ListView:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    Assembly myAssembly = this.GetType().GetTypeInfo().Assembly;
    IEnumerable<TypeInfo> myTypes = myAssembly.DefinedTypes;
    MyDefinedTypes.DataContext = myTypes;
}
Now, all that's left is to wire up the SelectionChanged event of the MyDefinedTypes list view, and have the event handler bind the selected TypeInfo object to the TypeInfoDetails StackPanel control:

private void MyDefinedTypes_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count > 0)
    {
        TypeInfo selectedTypeInfo = e.AddedItems.First() as TypeInfo;
        TypeInfoDetails.DataContext = selectedTypeInfo;
        TypeInfoDetails.Visibility = Windows.UI.Xaml.Visibility.Visible;
    }
}
Your completed MainPage class should now look like Listing 2.

Congratulations! The sample application's completed (it should look like Figure 1), and you can reflect upon your accomplishment.


[Click on image for larger view.]
Figure 1. The completed application.

As you can see, there are some major changes to the Type class API if you're coming from past .NET Frameworks and looking to create a Windows Store App. Note that the new APIs are also available in .NET 4.5 Desktop and Web applications, as well as Portable Class libraries. I think the new APIs are cleaner, with their IEnumerable collections and division between reference and definition Type reflection usage.

About the Author

Eric Vogel is a Senior Software Developer for Red Cedar Solutions Group in Okemos, Michigan. He is the president of the Greater Lansing User Group for .NET. Eric enjoys learning about software architecture and craftsmanship, and is always looking for ways to create more robust and testable applications. Contact him at [email protected].

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events