###Compiling an expression to a lambda
Today I had to convert a binary expression to a lambda and then use in a where clause on a collection. Easy enough, I thought, make an ExpressionLambda, compile it, substitute it into the where clause, no worries.
This is the first cut of the code:
The expression is a basic one - it calls an equality comparison on a property off an object and a constant. It is equivalent to this:
Googling for this exception and just general expression and lambda stuff kinda hints at people having the same problem as I am but with no fast solution. It was Jon Skeet’s answer to question I didn’t understand on StackOverflow that finally put me onto the right track.
In order to compile a lambda from an expression, you need to provide all instances of ParameterExpression that appear in the expression tree when creating a lambda expressionn (i.e. when calling Expression.Lambda<T>(Expression, params ParameterExpression[])). The Expression engine will not match types and names parameters in an expression - as far as it’s concerned different instances of ParameterExpression are discrete parameters.
Rewriting the above code yields something that doesn’t crash:
As you can see, we reused the instance variable in both expression declaration and Expression.Lambda call. Everything works fine now.
###Getting the parameters from Expression at runtime
My situation was such as that I had to deal with an already created expression. So I couldn’t simply take the variable parameters that are used to create an expression and reuse them when creating a lambda. The solution was to traverse the expression tree and get a list of all the ParameterExpression instances that are contained in the expression and pass those to Lambda function.
Luckily, ExpressionVisitor API provides an easy way to achieve this. All you have to do is inherit from ExpressionVisitor and implement one function to trap all the goodies we need:
We can even create an extension method to hide all complexity of creating a lambda: