私はJosephAlbahariによって書かれたPredicateBuilder
拡張メソッドを理解してきましたが、これは_Expression.Invoke
_でしたが、正直なところ、次のメソッドではその理由を理解できませんでした。
_public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>>
expr1, Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2,
expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
_
彼はそれを少し説明しましたが:
興味深い作業は、AndメソッドとOrメソッドの内部で行われます。まず、最初の式のパラメータを使用して2番目の式を呼び出します。 Invoke式は、指定された式を引数として使用して、別のラムダ式を呼び出します。最初の式の本体と2番目の式の呼び出されたバージョンから条件式を作成できます。最後のステップは、これを新しいラムダ式でラップすることです。
[〜#〜] msdn [〜#〜] は次のことを教えてくれます:
デリゲート式またはラムダ式を引数式のリストに適用するInvocationExpressionを作成します。
これは私には少し意味があります。したがって、基本的に、そのような式を使用する場合は、引数を渡す必要はありません。
でもどういうわけかよくわからなかった。多分私は疲れているか何かです。
質問:
InvocationExpression
を使用するのが理にかなっています。Or<T>
_メソッド(または_AndElse<T>
_)メソッドがどのように機能するかを誰かが説明できますか?更新:
仕事から家に帰るときにInvocationExpression
について考えていたところ、次のように頭に浮かびました。
メソッドを呼び出すときは、単純にCallMe(phoneNumber, time);
と言います。これは、メソッド呼び出しと呼ばれます。その場合、InvocationExpression
はCallMe(phoneNumber, time);
を表す式である必要があります。これは、_t => t + 2
_などのラムダを表すLambdaExpression
に似ています。したがって、基本的には、(パラメーターではなく)引数に適用されるメソッド呼び出しです。したがって、呼び出しとして、パラメーターは必要なくなりますが、引数が既にパラメーターに適用されているため、おそらく何かを返します。
私が話しているコードの詳細については、 http://www.albahari.com/nutshell/predicatebuilder.aspx にアクセスしてください。
エクスプレッションではなく、デリゲートを使用していると想像してください。次に、次のようにOr
と書くことができます。
_public static Func<T, bool> Or<T>(this Func<T, bool> expr1, Func<T, bool> expr2)
{
return x => expr1(x) || expr2(x);
}
_
_||
_を使用して組み合わせて、2つのデリゲートを呼び出す新しいデリゲートを作成します。式を使用するようにこれを書き直すと、デリゲートを呼び出すとExpression.Invoke()
になります。
_public static Expression<Func<T, bool>> Or<T>(
this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
var parameter = Expression.Parameter(typeof(T), "x");
var invokedExpr1 = Expression.Invoke(expr1, parameter);
var invokedExpr2 = Expression.Invoke(expr2, parameter);
return Expression.Lambda<Func<T, bool>>(
Expression.OrElse(invokedExpr1, invokedExpr2), parameter);
}
_
実際のOr
がこのように記述されていない理由は、(ほとんどの場合)最適化です。両方の式を呼び出す必要はなく、どちらか一方の本体とパラメーターを再利用できます。 (ただし、パラメーターが異なるため、両方を再利用することはできません。)