User Tools

Site Tools


notes:uwp:reflection

Reflection in UWP

UWP hides most of Type's members, and exposes them on a TypeInfo class instead, which you obtain by calling GetTypeInfo. TypeInfo exposes properties that return IEnumerable<T>. UWP applications cannot access non-public members of types, and they cannot use Reflection.Emit.

Example: Reflect over the members of the String type:

// You can also use DeclaredProperties, DeclaredMethods, DeclaredEvents, etc.
IEnumerable<MemberInfo> members =
    typeof(String).GetTypeInfo().DeclaredMembers;

Example: Reflect over the String type:

var t = typeof(String).GetTypeInfo();
Debug.WriteLine(typeof(String).Name);
Debug.WriteLine(t.BaseType);
Debug.WriteLine(t.BaseType.AssemblyQualifiedName);
Debug.WriteLine(t.Assembly);
Debug.WriteLine(t.IsEnum);
Debug.WriteLine(t.IsPrimitive);
Debug.WriteLine(t.IsGenericType);
Debug.WriteLine(t.IsPublic);
Debug.WriteLine(t.IsNestedPublic);
Debug.WriteLine(t.IsValueType);

Example: Reflect over the StringBuilder's constructors and obtain information about the constructor that accepts a single parameter of type string:

ConstructorInfo info = typeof(StringBuilder).GetTypeInfo().DeclaredConstructors
    .FirstOrDefault (c =>
        c.GetParameters().Length == 1 &&
        c.GetParameters()[0].ParameterType == typeof(String));

Example: Reflect over the Int32 type and obtain the MethodInfo on the parameterless overload of the ToString method:

MethodInfo method = typeof(int).GetTypeInfo().DeclaredMethods
     .FirstOrDefault(m => m.Name == "ToString" && m.GetParameters().Length == 0);

Example: Display all public classes defined in an assembly:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
...
// A list that of classes defined in an assembly.
List<Type> classes = new List<Type>();
 
// To get a refrence to the assembly we need just a single type, for example DependencyObject.
Type rootType = typeof(DependencyObject);
TypeInfo rootTypeInfo = rootType.GetTypeInfo();
 
// Get the Assembly object from the Assembly property of the TypeInfo object.
Assembly assembly = rootTypeInfo.Assembly;
 
// Get all public classes defined in the assembly.
foreach (Type type in assembly.ExportedTypes)
{
    TypeInfo typeInfo = type.GetTypeInfo();
    if (typeInfo.IsPublic && rootTypeInfo.IsAssignableFrom(typeInfo))
        classes.Add(type);
}
 
// Sort the classes by their fully-qualified name.
classes.Sort((t1, t2) => { return String.Compare(t1.ToString(), t2.ToString()); });
 
// Display information about the classes.
foreach (Type type in classes)
{
    TypeInfo typeInfo = type.GetTypeInfo();
    List<ConstructorInfo> ctors = new List<ConstructorInfo>(typeInfo.DeclaredConstructors);
 
    Debug.WriteLine(type.ToString()); // fully-qualified name
    Debug.WriteLine("    Name: " + typeInfo.Name);
    Debug.WriteLine("    Parent: " + typeInfo.BaseType.GetTypeInfo().Name);
    Debug.WriteLine("    IsSealed: " + typeInfo.IsSealed.ToString());
 
    // In UWP, non-instantiable classes have protected constructors
    // rather than being declared as abstract.
    Debug.WriteLine("    Abstract: " + !ctors.Exists(c => c.IsPublic));
}

Partial output:

Windows.UI.Xaml.Automation.Peers.AppBarAutomationPeer
    Name: AppBarAutomationPeer
    Parent: FrameworkElementAutomationPeer
    IsSealed: False
    Abstract: False
Windows.UI.Xaml.Automation.Peers.AutomationPeer
    Name: AutomationPeer
    Parent: DependencyObject
    IsSealed: False
    Abstract: True
Windows.UI.Xaml.Automation.Peers.ButtonAutomationPeer
    Name: ButtonAutomationPeer
    Parent: ButtonBaseAutomationPeer
    IsSealed: False
    Abstract: False
Windows.UI.Xaml.Automation.Peers.ButtonBaseAutomationPeer
    Name: ButtonBaseAutomationPeer
    Parent: FrameworkElementAutomationPeer
    IsSealed: False
    Abstract: True
Windows.UI.Xaml.Automation.Peers.CaptureElementAutomationPeer
    Name: CaptureElementAutomationPeer
    Parent: FrameworkElementAutomationPeer
    IsSealed: False
    Abstract: False
...

Example: Obtain the assembly version:

public string GetAssemblyVersion()
{
    // The typeof(.) argument could be any class in the App.
    Assembly asm = typeof(Book).GetTypeInfo().Assembly;
 
    // Method #1
    AssemblyFileVersionAttribute attr = 
        CustomAttributeExtensions.GetCustomAttribute<AssemblyFileVersionAttribute>(asm);
 
    if (attr != null)
        return attr.Version;
    else
        return "";
 
    // Method #2
    //return asm.GetName().Version.ToString();
}
notes/uwp/reflection.txt · Last modified: 2017/07/25 by leszek