C#中GetType().GetProperty返回null但属性存在的问题求助
解决Dynamic类型反射获取属性值的空引用问题
你的问题核心是**GetProperty可能没找到对应的属性**,导致property变量为null,调用GetValue时触发空引用异常。虽然调试时能看到属性、直接访问row.Site也正常,但dynamic类型的底层实现可能和你预期的不一样——很多CSV库返回的dynamic行(比如CsvHelper的动态记录)并不是常规的CLR对象,而是通过IDynamicMetaObjectProvider实现的动态类型,常规反射的GetProperty无法识别这些动态属性。
给你几个可靠的解决方法:
方法1:修正反射的绑定标志
如果你的dynamic对象是常规CLR类型(只是用dynamic声明),可能是属性名称大小写不匹配导致GetProperty返回null。加上忽略大小写的绑定标志即可:
Type type = row.GetType(); // 指定绑定标志,确保能匹配到公共实例属性,且忽略大小写 PropertyInfo property = type.GetProperty( "Site", BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase ); if (property != null) { // 先获取值,再转字符串,避免值本身为空的情况 object rawValue = property.GetValue(row); string propertyValue = rawValue?.ToString(); } else { // 这里可以加日志或处理属性不存在的逻辑 }
方法2:利用ExpandoObject/字典特性(推荐)
多数CSV库返回的dynamic行本质是ExpandoObject,它实现了IDictionary<string, object>接口。直接转成字典获取值更高效可靠:
// 先判断是否是字典类型 if (row is IDictionary<string, object> dynamicDict) { if (dynamicDict.TryGetValue("Site", out object rawValue)) { string propertyValue = rawValue?.ToString(); // 这里处理你的业务逻辑 } else { // 处理属性不存在的情况 } }
方法3:用动态绑定的方式获取
如果你不想用反射或字典,也可以借助dynamic的特性,通过字符串名称动态访问(需要引用Microsoft.CSharp程序集):
using Microsoft.CSharp.RuntimeBinder; try { dynamic dynamicRow = row; string propertyValue = dynamicRow.Site?.ToString(); } catch (RuntimeBinderException) { // 处理属性不存在的异常 }
这个方法和你直接写row.Site逻辑一致,若要通过变量指定属性名,可结合反射生成动态调用(不过对于新手来说,方法2的字典方式更直观)。
内容的提问来源于stack exchange,提问作者Иван Комаров
相关产品推荐
相关产品推荐

