0

http://www.albahari.com/nutshell/predicatebuilder.aspxの PredicateBuilder クラスを使用しています

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

この拡張メソッドは、OR 演算子を使用して Predicates をチェーンしています。ページには、説明が書かれています

最初の式のパラメーターを使用して 2 番目の式を呼び出すことから始めます。Invoke 式は、指定された式を引数として使用して、別のラムダ式を呼び出します。最初の式の本体と 2 番目の式の呼び出しバージョンから条件式を作成できます。最後のステップは、これを新しいラムダ式でラップすることです。


たとえば、私が持っている場合

Predicate<Book> p1 = b => b.Title.Contains("economy");
Predicate<Book> p2 = b=>b.PublicationYear>2001;
Predicate chain = p1.And(p2);

説明がよくわかりませんでした。上記の拡張メソッドのコードがどのように機能しているかを誰か説明してもらえますか? ありがとう

4

1 に答える 1

0

メソッド本体を次のように書き換えましょう。

return Expression.Lambda<Func<T, bool>>(
    Expression.OrElse(
        expr1.Body,
        Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>())
    ),
    expr1.Parameters);

また、 を受け取ってを返すexpr1既存の式であることにも留意する必要があります。さらに、私たちが取り組んでいる式ツリーは実際には何もしませんが(代わりに何かを表しています)、読みやすくするために今後は "do" を使用します。技術的には、式ツリーが実際に何かを行うには、最初にコンパイルしてから、結果のデリゲートを呼び出す必要があります。Tbool

さて、ここには何がありますか?これは、パラメータが取るものは何でも取るラムダ式であり(最後の行を参照)、ドキュメントexpr1に従って、その本体は

BinaryExpression最初のオペランドが false と評価された場合にのみ 2 番目のオペランドを評価する条件付き OR 演算を表す a 。

最初のオペランドは ですexpr1.Body。これは、結果の関数 (実際には関数ではありません。上記の注を参照) が を評価することを意味しますexpr1。結果が出ればその場trueで返しますtrueexpr2それ以外の場合は、渡されたものと同じパラメーターexpr1(これは単一のパラメーターを意味します)で呼び出しT、その結果を返します。

于 2013-03-15T15:42:32.133 に答える