5

以下の簡単なスニペットでは:

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();
}

compile メソッドが失敗し、InvalidOperationException

「タイプ 'System.String' の変数 's' がスコープ '' から参照されていますが、定義されていません」.

他の同様の質問を見つけましたが、提供された回答を理解できませんでした。

LambdaExpression の DebugView には次が含まれます。

.Lambda #Lambda1<System.Func`2[System.String,System.Boolean]>(System.String $s) {
    $s == "test"
}

したがって、この質問の他の例で見た場合、パラメーターと使用法が一致しませんが、これはここでは問題ではないようです。私は何を間違っていますか?

4

1 に答える 1

9

ラムダ式のパラメーターは、名前に基づく等式を使用せず、参照の等式を使用します。したがって、式には、と呼ばれる2つのまったく異なるパラメーターがsあり、1つは定義されているが使用されていない、もう1つは使用されているが定義されていない。

つまり、基本的に、式はのようなものs1 => s2 == "test"であるため、コンパイルに失敗します。最も簡単な修正は、元の式が使用するのと同じパラメーターを使用することです。

LambdaExpression lambda = Expression.Lambda(equal.Body, equal.Parameters.Single());

本当に独自のパラメーターを使用したい場合は、ラムダ本体の元のパラメーターのすべてのインスタンスを新しいパラメーターに置き換える必要があります。おそらくそれを行うための最良の方法はを使用することExpressionVisitorです。

于 2013-01-22T19:16:17.927 に答える