Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 不改变参数上下文的复杂表达式树_C#_Reflection_Expression Trees - Fatal编程技术网

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不,你没有;我认为你在我给出的例子中犯了一个转录错误