PredicateBuilder方法澄清

时间:2010-10-26 21:44:35

标签: c# .net expression-trees linqpad predicatebuilder

我查看了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);
  }

为什么调用新的lambda而不是仅仅使用OrElse作为谓词体?

2 个答案:

答案 0 :(得分:4)

我认为这是打字问题:Expression.OrElse会返回一个简单的表达式,而不是Expression<Func<T, bool>>

答案 1 :(得分:0)

我也不是100%肯定,但我认为问题在于确保每个表达式Func<T,bool>被链接,参数( T 的实例)始终是每个表达式都有相同的实例。

换句话说,对于:

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

我们假设t1和t2在引用上相等,但InvocationExpression确保它们基本上是这样说:“使用 expr1 中的参数创建一个调用 expr2 的新表达式”

另见PredicateBuilder Revisited作者,Mono的贡献者,真正明确地检查参数的引用相等性。