简体   繁体   中英

How to invoke Lambda expression using Expression class?

I have an expression that contains Func<,> delegate. I'm trying to invoke it and to get the integer value as result

class Program
{
    static Expression TestMethod(Expression<Func<int, int>> expression)
    {
        return expression;
    }

    static void Main(string[] args)
    {
        var expr = TestMethod(i => i + 1);

        var result = Expression.Lambda<Func<int, int>> (expr).Compile().Invoke(1);

        Console.WriteLine(result);
    }
}

When I Invoke expression, I get next error:

Unhandled Exception: System.ArgumentException: Incorrect number of parameters supplied for lambda declaration at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection 1 parameters, String paramName) at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String name, Boolean tailCall, IEnumerable 1 parameters) at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean tailCall, IEnumerable`1 parameters) at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, ParameterExpression[] parameters) at TestConsoleApp.Program.Main(String[] args) in E:\\programming\\portfolio\\TestConsoleApp\\TestConsoleApp\\Program.cs:line 22

How can I get the result of the Func<,> delegate invocation?

You're wrapping a lambda in a lambda... this is not what you want. Try this:

class Program
{
    static void Main(string[] args)
    {
        Expression<Func<int, int>> expr = i => i + 1;

        var result = expr.Compile().Invoke(1);

        Console.WriteLine(result);
    }
}

If you want to use the "passthrough" TestMethod, you can do this:

class Program
{
    static Expression TestMethod(Expression<Func<int, int>> expression)
    {
        return expression;
    }

    static void Main(string[] args)
    {
        var expr = TestMethod(i => i + 1);

        var result = ((Expression<Func<int, int>>)expr).Compile().Invoke(1);

        Console.WriteLine(result);
    }
}

Or if you want to rebuild the lambda from a non-generic expression:

class Program
{
    static LambdaExpression TestMethod(Expression<Func<int, int>> expression)
    {
        return expression;
    }

    static void Main(string[] args)
    {
        var expr = TestMethod(i => i + 1);

        var result = Expression.Lambda<Func<int, int>>(expr.Body, expr.Parameters).Compile().Invoke(1);

        Console.WriteLine(result);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM