C# 不改变参数上下文的复杂表达式树
我需要以友好的方式生成如下表达式:C# 不改变参数上下文的复杂表达式树,c#,reflection,expression-trees,C#,Reflection,Expression Trees,我需要以友好的方式生成如下表达式: Expression<Func<MyClass, bool>> expr = x => (x.SomeField.CompareTo(someValue) <= 0); var paramExpr = Expression.Parameter(typeof(MyClass), "x"); Expression<Func<MyClass, FieldType>> pathToField = x =&g
Expression<Func<MyClass, bool>> expr = x => (x.SomeField.CompareTo(someValue) <= 0);
var paramExpr = Expression.Parameter(typeof(MyClass), "x");
Expression<Func<MyClass, FieldType>> pathToField = x => x.SomeField;
Expression path = pathToField;
if (!(path is LambdaExpression lambdaMember))
throw ...;
Expression valueExpr = Expression.Constant(someValue);
var bodyExpr = Expression.LessThanOrEqual(Expression.Call(lambdaMember.Body, "CompareTo", null, valueExpr ), Expression.Constant(0));
return Expression.Lambda<Func<MyClass, FieldType>>(bodyExpr, paramExpr);
表达式expr=x=>(x.SomeField.CompareTo(someValue)x.SomeField;
表达式路径=路径域;
如果(!(路径为LambdaExpression lambdamber))
扔。。。;
表达式valueExpr=表达式常数(someValue);
var bodyExpr=Expression.LessThanOrEqual(Expression.Call(lambdamber.Body,“CompareTo”,null,valueExpr),Expression.Constant(0));
返回表达式.Lambda(bodyExpr,paramExpr);
但在尝试编译此文件时总是出现错误:
从作用域“”引用了类型为“MyClass”的变量“x”,但未定义该变量
我怎样才能正确地做到这一点呢?这里的问题是,您使用的是
lambdamber.Body
,它引用了x=>x.SomeField
中的x
,但是因为您只使用了.Body
,这是未定义的,并且与表达式.Parameter(typeof(MyClass),“x”)中的x
无关;
在一般情况下,这里有两个选项:
- 调用整个lambda(即
,而不是lambdamber
),传递用于参数的参数lambdamber.Body
- 在运行时重写内部lambda,使用-将
的实例从内部表达式中替换为要用作参数的任何对象-可能是x
paramExpr
表达式。调用:
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(Expression.Invoke(lambdaMember, paramExpr),
"CompareTo", null, valueExpr), Expression.Constant(0));
注意:在这种情况下还有第三个选项,因为这是一个相对简单的示例-您可以从内部表达式劫持参数并使用它,而不是将paramExpr
声明为新的参数表达式:
var paramExpr = lambdaMember.Parameters.Single();
Expression valueExpr = Expression.Constant(someValue);
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(lambdaMember.Body,
"CompareTo", null, valueExpr), Expression.Constant(0));
return Expression.Lambda<Func<MyClass, FieldType>>(bodyExpr, lambdaMember.Parameters);
var parametexpr=lambdamber.Parameters.Single();
表达式valueExpr=表达式常数(someValue);
var bodyExpr=Expression.lessthanRequal(
Expression.Call(lambdamber.Body,
“CompareTo”,null,valueExpr),表达式常数(0);
返回表达式Lambda(bodyExpr,lambdamber.Parameters);
var bodyExpr
有一个尾随},
谢谢,但是在第三个选项中,你只得到x=>x.Field.CompareTo(value)
,而不是x=>x.Field.CompareTo(value)@RazorRevenant不,你没有;我认为你在我给出的例子中犯了一个转录错误