How to get declared and inherited elements from TypeInfo

In the new Reflection API, the TypeInfo.Declared* properties are the correct way to access members (fields, properties, methods, etc.) declared by type. However, these properties do not include members inherited from the base class.

The old TypeInfo.GetRuntime*() methods return both declared and inherited elements, but are not available on all platforms, including .NET Core.

How to get list of declared and inherited members with new API?

+5
source share
1 answer

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(); } } } 

It should be very easy to use. A call to typeInfo.GetAllProperties() , for example, will return all DeclaredProperties current type and any base types, down to the inheritance tree.

I do not find any orders here, so if you need to list the members in a specific order, you may need to configure 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 .NET 4.5+ desktop and .NET Core.

+16
source

Source: https://habr.com/ru/post/1242902/


All Articles