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

  • Creating Reactive Applications in .NET

    In modern applications, data is being retrieved in asynchronous, real-time streams, as traditional pull requests where the clients asks for data from the server are becoming a thing of the past.

  • AI for GitHub Collaboration? Maybe Not So Much

    No doubt GitHub Copilot has been a boon for developers, but AI might not be the best tool for collaboration, according to developers weighing in on a recent social media post from the GitHub team.

  • Visual Studio 2022 Getting VS Code 'Command Palette' Equivalent

    As any Visual Studio Code user knows, the editor's command palette is a powerful tool for getting things done quickly, without having to navigate through menus and dialogs. Now, we learn how an equivalent is coming for Microsoft's flagship Visual Studio IDE, invoked by the same familiar Ctrl+Shift+P keyboard shortcut.

  • .NET 9 Preview 3: 'I've Been Waiting 9 Years for This API!'

    Microsoft's third preview of .NET 9 sees a lot of minor tweaks and fixes with no earth-shaking new functionality, but little things can be important to individual developers.

  • Data Anomaly Detection Using a Neural Autoencoder with C#

    Dr. James McCaffrey of Microsoft Research tackles the process of examining a set of source data to find data items that are different in some way from the majority of the source items.

Subscribe on YouTube