c# - 如何从 TypeInfo 获取声明和继承的成员

标签 c# inheritance reflection .net-core

new Reflection API , TypeInfo.Declared* 属性是访问在类型上声明的成员(字段、属性、方法等)的正确方法。但是,这些属性不包括从基类继承的成员。

旧的 TypeInfo.GetRuntime*() 方法返回声明的和继承的成员,但并非在所有平台上都可用,包括 .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() 将返回当前类型和任何基类型的所有 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 兼容。

关于c# - 如何从 TypeInfo 获取声明和继承的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35370384/

相关文章:

c# - 匹配大型文本数据集——如何更快地匹配?

javascript - 子类互相覆盖对方的方法

java - 当我继承Thread时,类中的每个方法都在新Thread上运行吗?

algorithm - 如何将一条线反射到另一条线上

c# - uwp xaml 解析失败,类库 dll

c# - 使用 .net 2.0 从 C# 程序将焦点设置到已打开的 Internet Explorer 选项卡

c# - 写入时图像不更新..奇怪的事情发生了

java - 区分父类(super class)和子类之间的变量

c# - ASP.NET MVC 3 动态表单生成

java - 在运行时创建具有反射和泛型的类的数组