在下面的簡單代碼段中:
static void Main(string[] args)
{
Expression<Func<string, bool>> equal = s => s == "test";
LambdaExpression lambda = Expression.Lambda(equal.Body, Expression.Parameter(typeof(string), "s"));
lambda.Compile();
}
編譯方法失敗,出現InvalidOperationException
“範圍''引用的'System.String'類型的變量'',但未定義”。
雖然我發現了其他類似的問題,但我無法理解所提供的答案。
LambdaExpression的DebugView包含:
.Lambda #Lambda1<System.Func`2[System.String,System.Boolean]>(System.String $s) {
$s == "test"
}
那麼,我在這個問題上的其他例子已經看到,參數和使用不匹配起來,這似乎並沒有在這裡是一個問題。我究竟做錯了什麼?
lambda表達式的參數不使用基於名稱的相等性,它們使用引用相等性。因此,在您的表達式中,您有兩個完全不同的參數,稱為s
,一個已定義但未使用,另一個已使用但未定義。
所以,基本上,你的表達式類似於s1 => s2 == "test"
,這就是它無法編譯的原因。最簡單的解決方法是使用原始表達式使用的相同參數:
LambdaExpression lambda = Expression.Lambda(equal.Body, equal.Parameters.Single());
如果您真的想使用自己的參數,則需要使用新參數替換lambda正文中原始參數的所有實例。可能最好的方法是使用ExpressionVisitor
。