In the new Reflection API, the TypeInfo.Declared*
properties are the right way to access the members (fields, properties, methods, etc) declared on a type. However, these properties do not include members inherited from a base class.
The old TypeInfo.GetRuntime*()
methods return both declared and inherited members, but are not available on all platforms, including .NET Core.
How do I get a list of declared and inherited members with the new API?
I wrote a set of small extension methods that provide this functionality:
public static class TypeInfoAllMemberExtensions
{
public static IEnumerable<ConstructorInfo> GetAllConstructors(this TypeInfo typeInfo)
=> GetAll(typeInfo, ti => ti.DeclaredConstructors);
public static IEnumerable<EventInfo> GetAllEvents(this TypeInfo typeInfo)
=> GetAll(typeInfo, ti => ti.DeclaredEvents);
public static IEnumerable<FieldInfo> GetAllFields(this TypeInfo typeInfo)
=> GetAll(typeInfo, ti => ti.DeclaredFields);
public static IEnumerable<MemberInfo> GetAllMembers(this TypeInfo typeInfo)
=> GetAll(typeInfo, ti => ti.DeclaredMembers);
public static IEnumerable<MethodInfo> GetAllMethods(this TypeInfo typeInfo)
=> GetAll(typeInfo, ti => ti.DeclaredMethods);
public static IEnumerable<TypeInfo> GetAllNestedTypes(this TypeInfo typeInfo)
=> GetAll(typeInfo, ti => ti.DeclaredNestedTypes);
public static IEnumerable<PropertyInfo> GetAllProperties(this TypeInfo typeInfo)
=> GetAll(typeInfo, ti => ti.DeclaredProperties);
private static IEnumerable<T> GetAll<T>(TypeInfo typeInfo, Func<TypeInfo, IEnumerable<T>> accessor)
{
while (typeInfo != null)
{
foreach (var t in accessor(typeInfo))
{
yield return t;
}
typeInfo = typeInfo.BaseType?.GetTypeInfo();
}
}
}
This should be super easy to use. Calling typeInfo.GetAllProperties()
, for example, will return all of the DeclaredProperties
of the current type and any base types, all the way up the inheritance tree.
I'm not imposing any ordering here, so if you need to enumerate members in a specific order, you may have to tweak the logic.
Some simple tests to demonstrate:
public class Test
{
[Fact]
public void Get_all_fields()
{
var fields = typeof(TestDerived).GetTypeInfo().GetAllFields();
Assert.True(fields.Any(f => f.Name == "FooField"));
Assert.True(fields.Any(f => f.Name == "BarField"));
}
[Fact]
public void Get_all_properties()
{
var properties = typeof(TestDerived).GetTypeInfo().GetAllProperties();
Assert.True(properties.Any(p => p.Name == "FooProp"));
Assert.True(properties.Any(p => p.Name == "BarProp"));
}
}
public class TestBase
{
public string FooField;
public int FooProp { get; set; }
}
public class TestDerived : TestBase
{
public string BarField;
public int BarProp { get; set; }
}
These extension methods are compatible with both desktop .NET 4.5+ and .NET Core.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With