【问题标题】:How to get declared and inherited members from TypeInfo如何从 TypeInfo 获取声明和继承的成员
【发布时间】:2016-02-12 19:08:23
【问题描述】:

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

旧的 TypeInfo.GetRuntime*() 方法返回声明的和继承的成员,但并非在所有平台上都可用,包括 .NET Core。

如何使用新 API 获取已声明的个继承成员的列表?

【问题讨论】:

    标签: c# inheritance reflection .net-core


    【解决方案1】:

    我编写了一组提供此功能的小型扩展方法:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-09
      • 1970-01-01
      • 2016-07-20
      • 1970-01-01
      • 2014-09-06
      • 2020-07-10
      • 1970-01-01
      • 2021-11-10
      相关资源
      最近更新 更多