簡體   English   中英

如何從TypeInfo獲取聲明和繼承的成員

[英]How to get declared and inherited members from TypeInfo

新的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兼容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM