果壳中的C#有一个名为PredicateBuilder免费类构造LINQ受可用一块一块谓词这里 。 下面是增加了一个新的表达式谓词的方法的提取物。 可能有人解释一下吗? (我已经看到了这个问题 ,我不想笼统的回答样子的。我要找的Expression.Invoke和Expression.Lambda如何建立新的表达具体的解释)。
public static Expression<Func<T, bool>> And<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.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
}
比方说,你有:
Expression<Func<Person, bool>> isAdult = p1 => p1.Age >= 18;
// I've given the parameter a different name to allow you to differentiate.
Expression<Func<Person, bool>> isMale = p2 => p2.Gender == "Male";
然后用它们组合起来PredicateBuilder
var isAdultMale = isAdult.And(isMale);
什么PredicateBuilder
产生的,看起来像这样的表达式:
// Invoke has no direct equivalent in C# lambda expressions.
p1 => p1.Age >= 18 && Invoke(p2 => p2.Gender == "Male", p1)
如你看到的:
- 将所得的λ 重用第一表达式的参数。
- 具有主体,通过使所述第一表达的参数作为用于第二表达式的参数的替换调用第二表达。 将所得
InvocationExpression
是有点像一个方法调用(由参数通过为参数调用例程)的表达当量。 -
And
S中的第一表达的身体和这个InvocationExpression
在一起以产生所得的λ的主体。
这个想法是,LINQ提供程序应该能够理解这个操作的语义和采取行动的一个明智的做法(如生成SQL一样WHERE age >= 18 AND gender = 'Male'
)。
时常想起,供应商有问题InvocationExpression
S,因为处理的明显并发症“的表达式内嵌套式呼叫”。
为了解决这个问题,LINQKit还提供了Expand
的帮手。 这实质上“内联”的调用呼叫巧妙通过与嵌套表达式的主体替换呼叫,适当地代嵌套表达式的参数的用途(在此情况下,替换p2
与p1
)。 这将产生类似:
p1 => p1.Age >= 18 && p1.Gender == "Male"
请注意,这怎么你会手动合并那些谓词,如果你在一个lambda自己这样做。 但随着LINQKit周围,你可以从独立的来源得到这些谓词和轻松地捆绑在一起:
- 如果没有“手动”表达代码编写。
- 可选地,在一种方式,是透明的消费者所得到的λ的。