Уточнение методов PredicateBuilder - PullRequest
2 голосов
/ 27 октября 2010

Я просмотрел PredicateBuilder источников, и его реализация делает меня любопытным. Давайте посмотрим на реализацию метода Or:

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

Почему он вызывает новую лямбду вместо того, чтобы просто использовать OrElse для тела предиката?

Ответы [ 2 ]

4 голосов
/ 27 октября 2010

Я считаю, что это проблема с печатанием: Expression.OrElse возвращает простое выражение, а не Expression<Func<T, bool>>.

0 голосов
/ 09 июля 2011

Я тоже не уверен на 100%, но я думаю, что проблема заключается в том, чтобы при каждом соединении каждого выражения Func<T,bool> параметр, который является экземпляром T , всегда был одним и тем же экземпляромдля каждого выражения.

Другими словами, для:

(t1 => t1>5).And(t2 => t2.Color == Blue)

мы предполагаем, что значения t1 и t2 равны, но InvocationExpression гарантирует, что они по сути говорят: «создайте новое выражение, котороевызывает expr2 с параметром из expr1".

См. также Повторное посещение PredicateBuilder , где автор, участник Mono, действительно явно проверяет наличиеэталонное равенство параметра.

...