使用Expression.PropertyOrField遍历获取Process类属性时迭代异常求助
问题分析与修复方案
嘿,我一眼就看到你代码里的关键问题了——你误用了Expression.PropertyOrField的方法重载,这才导致了“属性不存在”的异常。让我给你拆解清楚:
首先,.NET标准库中的Expression.PropertyOrField只有两个参数的版本:第一个是表达式(比如你的参数表达式),第二个是属性/字段的名字字符串。你写的Expression.PropertyOrField(mainParameter, typeof(Process), propertyPath)是错误的写法,根本不存在这个三参数重载,这就导致方法完全没法正确识别你要找的属性。
另外还有个小问题:你没必要在每次循环里都重新创建ParameterExpression,所有的成员表达式都应该绑定到同一个参数实例上,不然后续如果要把这些表达式组合成Lambda,会出现参数不匹配的坑。
修正后的完整代码
public List<MemberExpression> CreateMembers(string propertyPaths) { var memberExpressions = new List<MemberExpression>(); // 只创建一次参数,所有成员都绑定到同一个"e"参数上 var processParam = Expression.Parameter(typeof(Process), "e"); var propertyNames = propertyPaths.Split(',', StringSplitOptions.RemoveEmptyEntries); foreach (var propName in propertyNames) { // 使用标准的双参数重载,自动从processParam的类型(Process)查找属性 var memberExpr = Expression.PropertyOrField(processParam, propName); memberExpressions.Add(memberExpr); } return memberExpressions; }
几个关键的修复点
- 修正方法调用:删掉多余的
typeof(Process)参数,用标准的Expression.PropertyOrField(参数表达式, 属性名)写法,方法会自动从参数的类型(也就是Process)里查找对应的属性,不管是值类型属性还是你的虚拟导航属性(比如Diagnosis、Recommendation)都能正确识别。 - 复用参数表达式:把
ParameterExpression的创建移到循环外面,确保所有成员表达式都引用同一个参数实例。这不仅更高效,还能避免后续组合表达式时的参数不兼容问题。 - 代码可读性优化:调整了变量名,比如把
test改成memberExpressions,propertyPath改成propName,让代码逻辑更清晰。
测试建议
你可以传入类似"CompanyId,Diagnosis,RecommendationId"这样的字符串测试,修正后的代码应该能顺利创建对应Process类属性的MemberExpression,不会再抛出异常啦。
内容的提问来源于stack exchange,提问作者João Ox Oc
相关产品推荐
相关产品推荐

