我查看了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);
}为什么它调用新的lambda而不是只使用OrElse作为谓词主体?
发布于 2010-10-27 06:04:32
我认为这是一个类型问题:Expression.OrElse返回一个普通表达式,而不是一个Expression<Func<T, bool>>。
发布于 2011-07-09 15:52:23
我也不是百分之百确定,但我认为问题是确保当每个表达式Func<T,bool>被链接时,参数( T的实例)对于每个表达式总是相同的实例。
换句话说,对于:
(t1 => t1>5).And(t2 => t2.Color == Blue)我们假设t1和t2在引用上相等,但是InvocationExpression通过本质上说:“创建一个新的表达式,用expr1中的参数调用expr2”来确保它们是相等的。
另请参阅PredicateBuilder Revisited,其中作者是Mono的贡献者,真正显式地检查参数的引用相等性。
https://stackoverflow.com/questions/4028296
复制相似问题