GetProperties() 返回空数组主因是 BindingFlags 未配对;默认仅返回 public 实例属性,需显式添加 NonPublic、Static、FlattenHierarchy 等标志;GetValue() 报错因实例类型与 DeclaringType 不匹配;Attribute 取不到常因 AttributeUsage 设置不当;缓存应以 Type+BindingFlags 为键,注意泛型类型区分。
GetProperties() 返回空数组?检查 BindingFlags
反射拿不到属性,八成是 bindingflags 没配对。默认调用 typeof(myclass).getproperties() 只返回 public 实例属性,private、static、继承来的都不会出现。
- 要读 private 属性:加
BindingFlags.NonPublic - 要读 static 属性:加
BindingFlags.Static - 要读基类属性:加
BindingFlags.FlattenHierarchy(仅对 public/static 有效)或显式遍历基类 - 常用组合示例:
BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic
漏掉 BindingFlags.Instance 是新手高频坑——哪怕属性是实例的,不写它就只扫 static 成员。
PropertyInfo.GetValue() 报错“Object does not match target type”
这个错误不是值类型问题,而是传给 GetValue() 的对象实例和属性所属类型不匹配。比如你从 BaseClass 类型获取了属性,却把 DerivedClass 实例传进去,即使能隐式转换也不行。
- 确保
GetValue(obj)中的obj类型和PropertyInfo.DeclaringType完全一致(或为子类,但反射内部校验严格) - 如果属性定义在基类,而你用子类实例读取,建议直接用子类类型调用
GetProperties(),避免跨类型操作 - 值类型字段需注意装箱:对 struct 实例调用时,
GetValue()返回的是装箱后的 object,别误以为是引用传递
常见于工厂模式中缓存 PropertyInfo 后复用——缓存前必须确认声明类型与运行时实例类型兼容。
读取 [Obsolete] 或自定义 Attribute 时取不到?AttributeTargets 不匹配
GetCustomAttribute 返回 null,往往不是没打标签,而是标签没允许作用在属性上。
- 检查自定义 Attribute 类是否加了
[AttributeUsage(AttributeTargets.Property)] -
[Obsolete]默认只允许用在 method/class/property 等,但若你用在 field 上又试图用GetProperty()去查,自然找不到 - 读取时别漏参数:
PropertyInfo.GetCustomAttribute第二个参数控制是否查继承链,false 就只查当前属性自身(true)
尤其注意:.NET 5+ 对 AttributeUsage 的校验更严格,编译期不会报错,但运行时反射就是沉默失败。
性能敏感场景下,缓存 PropertyInfo 还是重新 GetProperties()?
反复调用 GetProperties() 开销不小,尤其是带复杂 BindingFlags 时;但盲目缓存 PropertyInfo 更危险。
- 缓存
PropertyInfo是安全的——它本身是不可变对象,且线程安全 - 不要缓存
GetProperties()的返回数组,因为每次调用都可能因类型加载顺序、泛型实例化等产生不同结果(尤其涉及动态程序集) - 推荐做法:按
Type+BindingFlags组合作为 key,用ConcurrentDictionary缓存PropertyInfo[] - 注意泛型类型:
typeof(List和) typeof(List是完全不同的 Type,不能共用缓存)
最易被忽略的一点:泛型类型参数变更时,DeclaringType 和 ReflectedType 行为会变化,缓存键里漏掉 IsGenericType 判断会导致静默错配。










