Search code examples
c#expressionargumentexception

Expressions... What am I doing wrong?


I've decided to take some golden time to learn a bit more about Expressions. I'm trying a very simple exercise, namely adding two numbers. I've hit an exception that's proving to be tricky to search for.

Here's my code

Expression<Func<int,int,int>> addExpr = (x, y) => x + y;
var p1 = Expression.Parameter(typeof(int), "p1");
var p2 = Expression.Parameter(typeof(int), "p2");
var lambda = Expression.Lambda<Func<int,int,int>>(addExpr, p1, p2); //<-here
var del = lambda.Compile();
var result = del(2,3); //expect 5

but this is throwing an ArgumentException : Expression of type 'System.Func`3[System.Int32,System.Int32,System.Int32]' cannot be used for return type 'System.Int32'

at the line indicated above. What have I done wrong?


Solution

  • You need to wrap the addExpr in an invoke using the expression parameters

    Expression<Func<int,int,int>> addExpr = (x, y) => x + y;
    var p1 = Expression.Parameter(typeof(int), "p1");
    var p2 = Expression.Parameter(typeof(int), "p2");
    var invokeExpression=Expression.Invoke(addExpr,p1,p2);
    var lambda = Expression.Lambda<Func<int,int,int>>(invokeExpression,p1,p2);
    var del = lambda.Compile();
    var result=del(2,3);
    

    The invoke is how you type p1 to x and p2 to y, alternatively you could just write the above as

    var p1 = Expression.Parameter(typeof(int), "p1");
    var p2 = Expression.Parameter(typeof(int), "p2");
    var lambda=Expresion.Lambda<Func<int,int,int>>(Expression.Add(p1,p2),p1,p2);
    var del = lambda.Compile();
    var result=del(2,3);
    

    Otherwise you need to grab the expression body into the lambda and pass the expression parameters.

    var lambda=Expresion.Lambda<Func<int,int,int>>(addExpr.Body,addExpr.Parameters);