Let's rewrite the method body like this:
return Expression.Lambda<Func<T, bool>>(
Expression.OrElse(
expr1.Body,
Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>())
),
expr1.Parameters);
We should also keep in mind that expr1
is your existing expression that takes a T
and returns a bool
. Additionally, while the expression trees we are working with do not actually do anything (they represent something instead), I am going to use "do" henceforth because it makes for much easier reading. Technically for an expression tree to actually do something you have to compile it first and then invoke the resulting delegate.
Ok, so what do we have here? This is a lambda expression that takes whatever parameters expr1
takes (see last line) and whose body, as per the documentation, is
a
BinaryExpression
that represents a conditional OR operation that evaluates the second operand only if the first operand evaluates to false.
The first operand is expr1.Body
, which means the resulting function (not actually a function, see note above) evaluates expr1
. If the result is true
it returns true
on the spot. Otherwise, it invokes expr2
with the same parameters as those passed to expr1
(this means the single T
parameter) and returns the result of that.