How to implement basic logical operations (AND, OR, NOT, XOR) with LINQ expressions:
1
public
static
class
ExpressionExtensions
2 {
3 public static Expression < Func < T, Boolean >> Or < T > ( this Expression < Func < T, Boolean >> expr, Expression < Func < T, Boolean >> other)
4 {
5 InvocationExpression invokedExpr = Expression.Invoke(other, expr.Parameters.Cast < Expression > ());
6 return (Expression.Lambda < Func < T, Boolean >> (Expression.OrElse(expr.Body, invokedExpr), expr.Parameters));
7 }
8
9 public static Expression < Func < T, Boolean >> Xor < T > ( this Expression < Func < T, Boolean >> expr, Expression < Func < T, Boolean >> other)
10 {
11 InvocationExpression invokedExpr = Expression.Invoke(other, expr.Parameters.Cast < Expression > ());
12 return (Expression.Lambda < Func < T, Boolean >> (Expression.ExclusiveOr(expr.Body, invokedExpr), expr.Parameters));
13 }
14
15 public static Expression < Func < T, Boolean >> Not < T > ( this Expression < Func < T, Boolean >> expr)
16 {
17 return (Expression.Lambda < Func < T, Boolean >> (Expression.Not(expr.Body), expr.Parameters));
18 }
19
20 public static Expression < Func < T, Boolean >> And < T > ( this Expression < Func < T, Boolean >> expr, Expression < Func < T, Boolean >> other)
21 {
22 InvocationExpression invokedExpr = Expression.Invoke(other, expr.Parameters.Cast < Expression > ());
23 return (Expression.Lambda < Func < T, Boolean >> (Expression.AndAlso(expr.Body, invokedExpr), expr.Parameters));
24 }
2 {
3 public static Expression < Func < T, Boolean >> Or < T > ( this Expression < Func < T, Boolean >> expr, Expression < Func < T, Boolean >> other)
4 {
5 InvocationExpression invokedExpr = Expression.Invoke(other, expr.Parameters.Cast < Expression > ());
6 return (Expression.Lambda < Func < T, Boolean >> (Expression.OrElse(expr.Body, invokedExpr), expr.Parameters));
7 }
8
9 public static Expression < Func < T, Boolean >> Xor < T > ( this Expression < Func < T, Boolean >> expr, Expression < Func < T, Boolean >> other)
10 {
11 InvocationExpression invokedExpr = Expression.Invoke(other, expr.Parameters.Cast < Expression > ());
12 return (Expression.Lambda < Func < T, Boolean >> (Expression.ExclusiveOr(expr.Body, invokedExpr), expr.Parameters));
13 }
14
15 public static Expression < Func < T, Boolean >> Not < T > ( this Expression < Func < T, Boolean >> expr)
16 {
17 return (Expression.Lambda < Func < T, Boolean >> (Expression.Not(expr.Body), expr.Parameters));
18 }
19
20 public static Expression < Func < T, Boolean >> And < T > ( this Expression < Func < T, Boolean >> expr, Expression < Func < T, Boolean >> other)
21 {
22 InvocationExpression invokedExpr = Expression.Invoke(other, expr.Parameters.Cast < Expression > ());
23 return (Expression.Lambda < Func < T, Boolean >> (Expression.AndAlso(expr.Body, invokedExpr), expr.Parameters));
24 }
25 }
Usages:
Expression<Func<int, bool>> isEven = i => (i % 2) == 0;
Expression<Func<int, bool>> isMultipleOfFive => i => (i % 5) == 0;
Expression<Func<int, bool>> evenOrMultipleOfFive = isEven.Or(isMultipleOfFive);
Expression<Func<int, bool>> isOdd = isEven.Not();
And so on.