2

我查看了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 作为谓词主体?

4

2 回答 2

4

我相信这是一个打字问题:Expression.OrElse返回一个普通的表达式,而不是一个Expression<Func<T, bool>>.

于 2010-10-26T22:04:31.807 回答
0

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

换句话说,对于:

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

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

另请参阅PredicateBuilder Revisited,其中作者(Mono 的贡献者)真正明确地检查参数的引用相等性。

于 2011-07-09T07:52:23.163 回答