Проблема здесь в том, что вы используете lambdaMember.Body
, который ссылается на x
из x => x.SomeField
- но поскольку вы только использовали .Body
, это не определено - и не связанона x
с Expression.Parameter(typeof(MyClass), "x");
В общем случае здесь есть 2 варианта:
- вызывает всю лямбду (то есть
lambdaMember
, не lambdaMember.Body
) - передача аргументов для использования в качестве параметров - перезапись внутренней лямбды во время выполнения с использованием
ExpressionVisitor
- выгрузка экземпляровx
из внутреннего выражения с тем, что вы хотите использовать в качестве аргумента - предположительно paramExpr
Первый вариант проще и просто Expression.Invoke
:
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);