如何通过C#反射获取基类型中定义的静态属性
根本原因
C# 中静态成员归属于声明它的类型自身,不会被派生类继承,这是反射API默认行为的设计依据:
- 调用
Type.GetProperties()不传绑定标志时,默认等价于传入BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static,这个查询规则只会返回:当前类型声明的所有公共静态/实例属性、继承链上所有基类的公共实例属性,不会返回任何基类声明的静态属性。 - 编译器允许你在派生类代码中直接写基类静态属性名,只是编译阶段的语法糖,本质上和写
基类名.静态属性名没有区别,不代表静态属性真的被派生类继承了。
实现方案
沿着类型的继承链向上递归遍历所有基类型,对每个基类型单独查询它自身声明的静态属性,和当前类型查询到的属性合并即可,注意去重避免多层继承场景下的重复结果。
可复用扩展方法代码
using System.Reflection; public static class TypeExtension { /// <summary> /// 获取类型所有属性,包含所有基类中定义的静态属性 /// </summary> public static IEnumerable<PropertyInfo> GetAllProperties(this Type type) { if (type == null) throw new ArgumentNullException(nameof(type)); // 第一步:获取当前类型的所有公共/非公共属性,包含自身静态、自身实例、继承链上的实例属性 var propList = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).ToList(); // 第二步:遍历继承链,逐个抓取每个基类自身声明的静态属性 var currentBase = type.BaseType; while (currentBase != null) { // 加DeclaredOnly标志,只拿当前基类自己声明的成员,避免重复拿到已经捕获的实例属性 var baseStaticProps = currentBase.GetProperties( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly ); propList.AddRange(baseStaticProps); currentBase = currentBase.BaseType; } return propList.Distinct(); } }
测试调用
替换你原Main方法中的查询逻辑即可,注意原代码中Console.log是笔误,C#中正确写法是Console.WriteLine:
static void Main(string[] args) { var type = typeof(B); foreach (var propertyInfo in type.GetAllProperties()) { Console.WriteLine(propertyInfo); } }
运行输出
System.String STATIC_Prop System.String Prop System.String BaseProp System.String STATIC_BaseProp
提示:如果只需要公共属性,移除
BindingFlags中的NonPublic枚举值即可;如果需要支持非公共属性,保留即可。你可以根据自己的业务场景调整绑定标志的组合。
内容的提问来源于stack exchange,提问作者Olli
相关产品推荐
相关产品推荐

