我正在創建表達式樹,並且存在一種情況,我需要在另一個lambda中創建一個lambda並將內部一個存儲在類中,並在表達式樹中添加該類。 這是什麼,我試圖做簡單的例子(這個代碼不編譯):表達式樹 - 在外部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();
}
}
}
問題是在GetOuterLambda
方法GetInnerLambda().Compile()
線。 我知道一個解決方案 - 它在代碼的註釋部分。有了這一切,一切工作正常,但我需要一個包裝作爲返回值,而不是表達式子樹(它可以將內部lambda子樹存儲在LambdaWrapper中,稍後編譯它,但同樣的問題發生)。
我得到的錯誤是Unhandled Exception: System.InvalidOperationException: variable 'Param' of type 'System.Object' referenced from scope '', but it is not defined
。
如果我添加Param
來阻止內部lambda中的變量,代碼編譯,但Param沒有在外部lambda中賦值(這是有道理的)。
這怎麼解決?
感謝您的回答。我不喜歡這種方法是這些lambda表達式是實際的函數,他們可以有他們的參數(我沒有包括那個部分有問題,因爲我沒有問題),Param不僅僅是可變我需要訪問的(有可能是他們中的很多),所以我不認爲addig人工參數來解決作用域是非常優雅的解決方案。 –
更新的答案可能只是爲我工作,但我得查,當我回到我的工作電腦。謝謝... –
我檢查了這是否適用於我。幾乎:)。我更進一步,創建了DynamicExpression來創建LambdaWrapper的實例。我不得不創建粘合劑,所以這種營養需要更多的工作,但是我的主要項目中已經有了它們。感謝您在解決此問題中表現出的興趣:) –