GetProperties()返回空数组主因是BindingFlags未配对;默认仅返回public实例属性,需显式添加NonPublic、Static、FlattenHierarchy等标志;泛型类反射须用MakeGenericType构造封闭类型,继承属性需手动遍历基类。
GetProperties() 返回空数组的常见原因
反射拿不到属性,大概率不是代码写错,而是访问级别或泛型/继承干扰导致。默认
只返回
实例属性,且不递归基类——哪怕你写了
或
,父类的
属性也不会自动出现。
要包含非 public 属性(如
、
),必须显式传入
:
要包含基类属性,得手动向上遍历:
,.NET 没有内置“全继承链属性”快捷方法
泛型类实例(如
)反射时要用
获取泛型定义,再调用
构造封闭类型,否则
会失败或返回空
Activator.CreateInstance() 创建泛型实例的坑
直接传泛型类型参数给
很容易报
,因为没区分开放泛型和封闭泛型。
开放泛型类型(如
)不能直接实例化,必须先构造封闭类型:
带构造参数的泛型类(如
),不能靠
自动解析依赖,它不走 DI 容器逻辑——此时应改用
性能敏感场景慎用
:它比直接 new 慢 5–10 倍。高频创建建议缓存
或预编译表达式树
PropertyInfo.SetValue() 报 TargetException 的真实含义
并不表示属性不存在,而是目标对象与属性所属类型不匹配——比如你用
拿到的是
的
,却试图对一个
实例(虽继承自
)调用
,而该属性在
中被重写为
字段,则会失败。
C知道
CSDN推出的一款AI技术问答工具
下载
检查属性是否是
且被
:此时应通过
(而非基类类型)获取,确保类型一致
值类型属性赋值时注意装箱:对
属性设
会抛异常,需先判断
(辅助方法需自行实现)
只读属性(只有
)调用
会静默失败(不报错但无效果),可用
提前校验
动态创建对象后如何安全绑定 JSON 数据
用反射创建实例后接
反序列化,常因属性名大小写、忽略只读字段等策略不一致导致绑定失败。
不要用
——它不会还原为你的目标类型,而是变成
或
正确做法是:先用
创建空实例,再用
注入数据(需启用
)
若目标类含
或
,
默认不识别这些特性,得传入自定义
并设置
等选项
反射链越长(类型推导 → 属性遍历 → 值设置 → 序列化注入),出问题的位置就越隐蔽。别依赖“看起来能跑”,每个环节都要验证
是否来自预期类型、
是否为 true、
是否成立——这些检查加起来不到三行,却能省掉半天调试时间。
GetProperties()publicvirtualoverridepublicprivateprotectedBindingFlagstypeof(MyClass).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)type.BaseType?.GetProperties(...)MyClasstypeof(MyClass<>)MakeGenericType(...)GetProperties()Activator.CreateInstance()ArgumentException: Type must be a runtime typetypeof(List<>)typeof(List<>).MakeGenericType(typeof(int))class Repo { public Repo(IOptions opts) {...} } Activator.CreateInstance(type, args)IServiceProvider.GetService(type)Activator.CreateInstance()ConstructorInfo.Invoke()TargetExceptionobj.GetType().GetProperty("Name")Person.NamePropertyInfoEmployeePersonSetValue()Employeenewvirtualoverrideobj.GetType().GetProperty("Name")intnullproperty.PropertyType.IsNullable()getSetValue()property.CanWriteSystem.Text.JsonJsonSerializer.DeserializeJsonElementDictionaryActivator.CreateInstance(targetType)JsonSerializer.Populate()PropertyNameCaseInsensitive = true[JsonIgnore][JsonPropertyName("xxx")]Populate()JsonSerializerOptionsIgnoreReadOnlyProperties = falsePropertyInfoCanWriteIsAssignableFrom()