変数 '' '' 型 '' がスコープ '' から参照されていますが、定義されていません 質問する

変数 '' '' 型 '' がスコープ '' から参照されていますが、定義されていません 質問する

次のコードは説明不要でしょう。And演算子を使用して 2 つの式を 1 つに結合したいのです。最後の行で rune-time にエラーが発生します。

追加情報: 'System.String' 型の変数 'y' がスコープ '' から参照されていますが、定義されていません

コード:

Expression<Func<string, bool>> e1 = y => y.Length < 100;
Expression<Func<string, bool>> e2 = y => y.Length < 200;

var e3 = Expression.And(e1.Body, e2.Body);

var e4 = Expression.Lambda<Func<string, bool>>(e3, e1.Parameters.ToArray());
e4.Compile(); // <--- causes run-time error

ベストアンサー1

他の回答に示されているように、 という名前のパラメータを持つ 2 つの式がありますy。それらは自動的に相互に関連付けられるわけではありません。

式を適切にコンパイルするには、ソース式の両方のパラメータを指定する必要があります。

Expression<Func<string, bool>> e1 = (y => y.Length > 0);
Expression<Func<string, bool>> e2 = (y => y.Length < 5);

var e3 = Expression.And(e1.Body, e2.Body);

// (string, string) by adding both expressions' parameters.
var e4 = Expression.Lambda<Func<string, string, bool>>(e3, new[] 
{ 
    e1.Parameters[0], 
    e2.Parameters[0] 
});

Func<string, string, bool> compiledExpression = e4.Compile();

bool result = compiledExpression("Foo", "Foo");

もちろん、両方の式を 1 つのパラメータのみで組み合わせた式が必要になります。次のように式を再構築できます。

ParameterExpression param = Expression.Parameter(typeof(string), "y");
var lengthPropertyExpression = Expression.Property(param, "Length");

var e1 = Expression.GreaterThan(lengthPropertyExpression, Expression.Constant(0));
var e2 = Expression.LessThan(lengthPropertyExpression, Expression.Constant(5));

var e3 = Expression.AndAlso(e1, e2);

var e4 = Expression.Lambda<Func<string, bool>>(e3, new[] { param });

Func<string, bool> compiledExpression = e4.Compile();

bool result = compiledExpression("Foo");

式を再構築するのではなく、既存の式の本体とパラメータで実行するというコメントについては、これは次ExpressionRewriterのように機能します。C# で 2 つのラムダ式を組み合わせるそしてAndAlsoから式の本体のパラメータ名を置き換える:

Expression<Func<string, bool>> e1 = (y => y.Length > 0);
Expression<Func<string, bool>> e2 = (z => z.Length < 10);

var e3 = ParameterReplacer.AndAlso<string>(e1, e2);

Func<string, bool> compiledExpression = e3.Compile();

bool result = compiledExpression("Foo");

おすすめ記事