Lambda 表达式以及如何组合它们?

发布于 2024-09-10 13:37:41 字数 841 浏览 2 评论 0原文

如何使用 OR 将两个 lambda 表达式合并为一个?

我已经尝试了以下方法,但合并它们需要我将参数传递到 Expression.Invoke 调用中,但是我希望将传递到新 lambda 的值传递到每个子 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 表达式合并为一个,并使子 lambda 的参数成为父表达式的参数?

How can I combine two lambda expressions into one using an OR ?

I have tried the following but merging them requires me to pass parameters into the Expression.Invoke calls, however I want the value passed into the new lambda to be passed onto each 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);

Any ideas how to combine two lambda expressions into one and have the arguments of the child lambdas be that of the parent ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

栀子花开つ 2024-09-17 13:37:41

我发现学习表达式的最好方法是查看 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 创建一个 InvocableExpression,将参数应用于您的 func2

事实上,PredicateBuilder 可能就是您所需要的一切。

var predicate = PredicateBuilder.False<int>();
predicate = predicate.Or(x => x > 5);
predicate = predicate.Or(x => x > 10);

我会修改“x > 5 or x > 10”,对于 OR 来说似乎是一件奇怪的事情。

希望有帮助。

The best way I found to learn expressions, is to take a look at the source code of PredicateBuilder.

When you want to combine multiple your statements, you can:

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);

The Expression.Invoke creates an InvocationExpression that applies the parameters to your func2.

In fact, PredicateBuilder may be everything you need.

var predicate = PredicateBuilder.False<int>();
predicate = predicate.Or(x => x > 5);
predicate = predicate.Or(x => x > 10);

I would revise "x > 5 or x > 10", seems like an odd thing to OR.

Hope that helps.

倾城泪 2024-09-17 13:37:41

听起来很有趣...我对 lambda 表达式不太了解,但我发现了 这篇文章。在 PredicateBuilder Source Code 下是一个适合我的 or 示例:

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 );
}

Sound interesting ... I don't know much about lambda expression, but I found this article. Under PredicateBuilder Source Code is an example for or that works for me:

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 );
}
悟红尘 2024-09-17 13:37:41

为什么不直接做:

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

节省了与第三方库的麻烦。

Why not just do:

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

?

Saves messing about with 3rd party libraries.

寂寞清仓 2024-09-17 13:37:41

** 编辑:哎呀,读完了 OR 的东西,更新了它 ***

嗨,

不确定你是否只是想单独称呼它们,或者你想从学术的角度将它们组合起来。

你可以这样称呼它们:

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 并看看它是如何构建的。

问候格特-扬

** edit: oops read over the OR thing, updated it ***

Hi,

Not sure if you just want to call them seperatley or you want to combine them from an academic point of view.

You can just call them like this:

bool OR(int i1, Func<int, bool> f1, Func<int, bool> f2){
    return f1(i1) || f2(i1);
}

That will do the trick.

or you can rewrite that as

bool MyOR = (i1, f1, f2) => f1(i1) || f2(i1);

And when you're qurious, create an expression from that and look at that. (doing this by hand, don;t have VS here now, so please be easy on my typos)

Expression<Func<int, Func<int, bool>, Func<int, bool>, bool>> exprOR = 
(i1, f1, f2) => f1(i1) || f2(i1); 

If you want to look at the anatomy of the expression, you can look at this article i wrote: http://www.codeproject.com/KB/WPF/WpfExpressionTree.aspx

Just pass the expression to the apadater and see how it;s built up.

Regards Gert-Jan

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文