Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda expressions and how to combine them?

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 ?

like image 944
Richard Friend Avatar asked Jul 20 '10 08:07

Richard Friend


1 Answers

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.

like image 109
Matthew Abbott Avatar answered Oct 12 '22 23:10

Matthew Abbott