我正在创建表达式树,有一种情况我需要在另一个 lambda 中创建一个 lambda,并将内部的一个存储在一个类中,然后将该类添加到表达式树中。这是我正在尝试做的简单示例(此代码无法编译):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace SimpleTest {
public class LambdaWrapper {
private Delegate compiledLambda;
public LambdaWrapper(Delegate compiledLambda) {
this.compiledLambda = compiledLambda;
}
public dynamic Execute() {
return compiledLambda.DynamicInvoke();
}
}
public class ForSO {
public ParameterExpression Param;
public LambdaExpression GetOuterLambda() {
IList<Expression> lambdaBody = new List<Expression>();
Param = Expression.Parameter(typeof(object), "Param");
lambdaBody.Add(Expression.Assign(
Param,
Expression.Constant("Value of 'param' valiable"))
);
lambdaBody.Add(Expression.Call(
null,
typeof(ForSO).GetMethod("Write"),
Param)
);
Delegate compiledInnerLambda = GetInnerLambda().Compile();
LambdaWrapper wrapper = new LambdaWrapper(compiledInnerLambda);
lambdaBody.Add(Expression.Constant(wrapper));
//lambdaBody.Add(GetInnerLambda());
return Expression.Lambda(
Expression.Block(
new ParameterExpression[] { Param },
lambdaBody));
}
public LambdaExpression GetInnerLambda() {
return Expression.Lambda(
Expression.Block(
Expression.Call(null,
typeof(ForSO).GetMethod("Write"),
Expression.Constant("Inner lambda start")),
Expression.Call(null,
typeof(ForSO).GetMethod("Write"),
Param),
Expression.Call(null,
typeof(ForSO).GetMethod("Write"),
Expression.Constant("Inner lambda end"))
)
);
}
public static void Write(object toWrite) {
Console.WriteLine(toWrite);
}
public static void Main(string[] args) {
ForSO so = new ForSO();
LambdaWrapper wrapper = so.GetOuterLambda().Compile()
.DynamicInvoke() as LambdaWrapper;
wrapper.Execute();
//(so.GetOuterLambda().Compile().DynamicInvoke() as Delegate).DynamicInvoke();
}
}
}
问题出GetInnerLambda().Compile()
在GetOuterLambda
方法上。我知道一种解决方案 - 它位于代码的注释部分。这样,一切正常,但我需要一个包装器作为返回值,而不是表达式子树(可以将内部 lambda 子树存储在 LambdaWrapper 中,然后再编译它,但会出现同样的问题)。
我得到的错误是Unhandled Exception: System.InvalidOperationException: variable 'Param' of type 'System.Object' referenced from scope '', but it is not defined
.
如果我Param
在内部 lambda 中添加块变量,代码会编译,但 Param 没有在外部 lambda 中分配值(这是有道理的)。
如何解决?