通过表达式树实现模型属性赋值时遇InvalidOperationException问题求助
解决表达式树赋值时的InvalidOperationException异常
问题场景:
你想要实现一个通过表达式树给模型属性赋值的方法,期望调用方式如下:
UpdateFeature(myFeature, x => x.MyProperty, "newValue");
其中myFeature的类型定义为:
class MyType { public string MyProperty { get; set; } }
但你编写的UpdateFeature方法在调用Compile时触发InvalidOperationException,错误信息:
variable 'x' of type 'MyType' referenced from scope '', but it is not defined
错误原因
你的代码里新建了一个ParameterExpression实例,但原表达式e中引用的x是另一个完全不同的参数实例——虽然两者类型相同,但不是同一个引用,导致表达式树在编译时认为引用的变量未在当前作用域定义。
修复后的代码
复用原表达式中的参数实例,而不是重新创建:
void UpdateFeature<T, TResult>(T feature, Expression<Func<T, TResult>> e, TResult newValue) { // 获取原表达式的参数(就是调用时写的x) var parameter = e.Parameters[0]; // 创建赋值表达式:将newValue赋值给指定属性 var assignExp = Expression.Assign(e.Body, Expression.Constant(newValue, typeof(TResult))); // 使用原参数构建lambda并编译执行 var lambda = Expression.Lambda<Action<T>>(assignExp, parameter); lambda.Compile()(feature); }
说明
- 复用原表达式的
Parameters[0],确保赋值表达式里的属性引用和lambda的参数属于同一个作用域,解决变量未定义的问题。 - 给
Expression.Constant指定typeof(TResult),避免当newValue为null时,常量表达式的类型推断不符合预期的情况。
测试示例:
var myFeature = new MyType(); UpdateFeature(myFeature, x => x.MyProperty, "newValue"); Console.WriteLine(myFeature.MyProperty); // 输出:newValue
内容的提问来源于stack exchange,提问作者MakePeaceGreatAgain
相关产品推荐
相关产品推荐

