如何从 TypeInfo 获取声明和继承的成员
How to get declared and inherited members from TypeInfo
在 new Reflection API 中,TypeInfo.Declared*
属性是访问在类型上声明的成员(字段、属性、方法等)的正确方法。但是,这些属性不包括从基础 class.
继承的成员
旧 TypeInfo.GetRuntime*()
方法 return 既声明成员又继承成员,但并非在所有平台上都可用,包括 .NET Core。
如何获取已声明的 和 继承成员的列表以及新的 API?
我写了一组提供此功能的小扩展方法:
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();
}
}
}
这个应该超级好用。例如,调用 typeInfo.GetAllProperties()
将 return 当前类型的所有 DeclaredProperties
和任何基类型,一直向上继承树。
我在这里没有强加任何顺序,所以如果您需要以特定顺序枚举成员,您可能需要调整逻辑。
一些简单的测试来演示:
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; }
}
这些扩展方法与桌面 .NET 4.5+ 和 .NET Core 兼容。
在 new Reflection API 中,TypeInfo.Declared*
属性是访问在类型上声明的成员(字段、属性、方法等)的正确方法。但是,这些属性不包括从基础 class.
旧 TypeInfo.GetRuntime*()
方法 return 既声明成员又继承成员,但并非在所有平台上都可用,包括 .NET Core。
如何获取已声明的 和 继承成员的列表以及新的 API?
我写了一组提供此功能的小扩展方法:
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();
}
}
}
这个应该超级好用。例如,调用 typeInfo.GetAllProperties()
将 return 当前类型的所有 DeclaredProperties
和任何基类型,一直向上继承树。
我在这里没有强加任何顺序,所以如果您需要以特定顺序枚举成员,您可能需要调整逻辑。
一些简单的测试来演示:
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; }
}
这些扩展方法与桌面 .NET 4.5+ 和 .NET Core 兼容。