如何使用OR?
将两个lambda表达式合并为一个我尝试过以下但是合并它们需要我将参数传递给 Expression.Invoke 调用,但是我想将传递给新lambda的值传递给每个child-lambda。
Expression<Func<int, bool>> func1 = (x) => x > 5;
Expression<Func<int, bool>> func2 = (x) => x < 0;
//Combines the lambdas but result in runtime error saying I need to pass in arguments
//However I want the argument passed into each child lambda to be whatever is passed into the new main lambda
Expression<Func<int, bool>> lambda = Expression.Lambda<Func<int, bool>>(Expression.Or(Expression.Invoke(func1), Expression.Invoke(func2)));
//The 9 should be passed into the new lambda and into both child lambdas
bool tst = lambda.Compile().Invoke(9);
如何将两个lambda表达式合并为一个并将子lambdas的参数组合成父类的参数?
答案 0 :(得分:18)
我发现学习表达式的最佳方法是查看PredicateBuilder的源代码。
如果要组合多个语句,可以:
Expression<Func<int, bool>> func1 = (x) => x > 5;
Expression<Func<int, bool>> func2 = (x) => x > 10;
var invocation = Expression.Invoke(func2, func1.Parameters.Cast<Expression>());
var expression = Expression.Lambda<Func<int, bool>>(Expression.OrElse(func1.Body, invocation), func1.Parameters);
Expression.Invoke
创建一个InvocationExpression,将参数应用于func2
。
事实上,PredicateBuilder可能就是你需要的一切。
var predicate = PredicateBuilder.False<int>();
predicate = predicate.Or(x => x > 5);
predicate = predicate.Or(x => x > 10);
我会修改“x > 5
或x > 10
”,对OR来说似乎很奇怪。
希望有所帮助。
答案 1 :(得分:1)
听起来很有趣......我对lambda表达不太了解,但我发现this article。在 PredicateBuilder源代码下是适用于我的或的示例:
public static Expression<Func<T, bool>> Or<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2 )
{
var invExpr = Expression.Invoke( expr2, expr1.Parameters.Cast<Expression>() );
return Expression.Lambda<Func<T, bool>>
( Expression.OrElse( expr1.Body, invExpr ), expr1.Parameters );
}
答案 2 :(得分:1)
为什么不这样做:
Func<int, bool> func1 = (x) => x > 5;
Func<int, bool> func2 = (x) => x > 10;
List<Func<int, bool>> funcs = new List<Func<int, bool>> { func1, func2 };
var value = 7;
Console.WriteLine(funcs.Any(x => x(value))); // OR
Console.WriteLine(funcs.All(x => x(value))); // AND
避免与第三方库混淆。
答案 3 :(得分:0)
**编辑:oops读取OR事物,更新它***
您好,
不确定您是否只想将它们称为seperatley,或者您想从学术角度将它们结合起来。
你可以像这样打电话给他们:
bool OR(int i1, Func<int, bool> f1, Func<int, bool> f2){
return f1(i1) || f2(i1);
}
这样就可以了。
或者您可以将其重写为
bool MyOR = (i1, f1, f2) => f1(i1) || f2(i1);
当你很谨慎的时候,从中创建一个表达式并查看它。 (手动完成这个,现在不要在这里使用VS,所以请在我的拼写错误中轻松完成)
Expression<Func<int, Func<int, bool>, Func<int, bool>, bool>> exprOR =
(i1, f1, f2) => f1(i1) || f2(i1);
如果你想看一下表达式的解剖,你可以看看我写的这篇文章:http://www.codeproject.com/KB/WPF/WpfExpressionTree.aspx
将表达式传递给apadater并查看它是如何构建的。
关心Gert-Jan