For the very first time I am exploring expression trees. I have a few basic doubts.
So essentially , an expression takes only a lambda expression . Ans then we can Compile() the lambda expression to MSIL code which in turn returns a generic delegate. We can invoke the returned delegate as it is . Is my understanding correct ?
If it is here is what I am trying to achieve: ((10*5)+(9/4))
BinaryExpression b1 = Expression.MakeBinary(ExpressionType.Multiply, Expression.Constant(10), Expression.Constant(5));//(10*5)
BinaryExpression b2 = Expression.MakeBinary(ExpressionType.Divide, Expression.Constant(9), Expression.Constant(4));//(9/4)
BinaryExpression b4 = Expression.MakeBinary(ExpressionType.Add, b1, b2);//((10*5)+(9/4))
So at this point we have made the lambda expression body
. Now to turn it to a full lambda expression
we need to call
Console.WriteLine(Expression.Lambda<Func<int, int>>(b4).Compile());
I am not getting this part . And this does not work also .
Why this Func<int,int>
?
Is it like the inner expressions will take only int as param and the entire expression will return an int?
Obviously this does not work. How the generated lambda looks like ?
I am getting the entire picture? How to make this work?
Expression.Lambda<Func<int, int>>(b4).Compile()
Func<int,int>
is a signature for lambdas that take a single int
parameter, and return an int
. Your lambda has a different signature.
Obviously this does not work.
Your lambda does not take any parameters, so you need Func<int>
instead.
How the generated lambda looks like?
Generated lambda is a callable object. If you would like to evaluate the expression that you get back, cast and call it, like this:
var compiledLambda = (Func<int>)Expression.Lambda<Func<int>>(b4).Compile();
Console.WriteLine(compiledLambda());
// ^^
The above prints 52
, as expected.
If you would like to make a Func<int,int>
, add a parameter to your expression, e.g. make it (p*5)+(9/4)
where p
is an int
parameter:
ParameterExpression p = Expression.Parameter(typeof(int));
BinaryExpression b1 = Expression.MakeBinary(ExpressionType.Multiply, p, Expression.Constant(5));//(p*5)
BinaryExpression b2 = Expression.MakeBinary(ExpressionType.Divide, Expression.Constant(9), Expression.Constant(4));//(9/4)
BinaryExpression b4 = Expression.MakeBinary(ExpressionType.Add, b1, b2);
var compiledLambda = (Func<int,int>)Expression.Lambda<Func<int,int>>(b4, new[] {p}).Compile();
Console.WriteLine(compiledLambda(10)); // Prints 52
Console.WriteLine(compiledLambda(8)); // Prints 42