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.
浙公网安备 33010602011771号