3

I have been reading Joseph Albahari's brilliant book on C# 4.0 and I came across this class:

public static class PredicateBuilder
    {
        public static Expression<Func<T, bool>> True<T> () { return f => true; }
        public static Expression<Func<T, bool>> False<T> () { return f => false; }

        public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
                                                  Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());

            return Expression.Lambda<Func<T, bool>>
                 (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
        }

        public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
                                                   Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
            return Expression.Lambda<Func<T, bool>>
                 (Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
        }
    }

Can anybody explain to me what this function is doing and how it works? I know it is used to add and and or conditions to the expression tree but how does it actually work? I have never used these classes like Expression and such. What is this specific code doing?

var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());

                return Expression.Lambda<Func<T, bool>>
                     (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);

I know Func is a delegate which should return either true or false but what is this code in general doing ?

Thanks in advance :)

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
TCM
  • 16,780
  • 43
  • 156
  • 254

1 Answers1

2

This is using Expression Trees to "build" a predicate from two input expressions representing predicates.

Expression Trees are a way to use lambda's to generate a representation of code in a tree like structure (rather than a delegate directly). This takes two expression trees representing predicates (Expression<Func<T,bool>>), and combines them into a new expression tree representing the "or" case (and the "and" case in the second method).

Expression trees, and their corresponding utilities like above, are useful for things like ORMs. For example, Entity Framework uses expression trees with IQueryable<T> to turn "code" defined as a lambda into SQL that's run on the server.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • @Kar: He's taking the two expressions, and building one that is effectively "expression1 || expression2" in the first case, and "expression1 && expression2" in the second case... – Reed Copsey Mar 14 '11 at 17:15
  • 1
    - Thanks he has created numerous such weird classes that go way beyond my head like ExpressionVisitor etc. I will post these doubts as i come across. – TCM Mar 14 '11 at 17:19
  • - Can you please tell me why has he used expr2 as 1st argument in Invoke and not expr1 and then pass expr2.parameters.cast as 2nd argument? – TCM Mar 14 '11 at 17:36