Search code examples
c#dynamicreflectionexpressionadapter

Incorrect number of arguments supplied for call to method C#


I have a method which takes 2 parameters. I want to build a method in runtime, which will call this method and pass one parameter by default. Another parameter will be passed in new function.

I tried to create lambda expression which calls this method but i've got an error: Incorrect number of arguments supplied for call to method.

static class Program
{
    static void Main(string[] args)
    {
        var method = typeof(Program).GetMethod("Method");
        // here i want to set first parameter as "parameter1" when new method will be called
        var lambda = Expression.Lambda<Func<string, string>>(Expression.Call(method, Expression.Constant("parameter1")));
        var adapter = lambda.Compile();
        // and here i wanna pass only one agrument - second (parameter2)
        var result = adapter("parameter2");

        // expected result "parameter1 ---- parameter2"
    }

    public static string Method(string parameter1, string parameter2)
    {
        return $"{parameter1} ---- {parameter2}";
    }

I wanna pass only second parameter when function will be called. First must be specified automatically.


Solution

  • You defined the constant, but you also need to define the other parameter so you can give it to Method:

    var method = typeof(Program).GetMethod("Method");
    // here i want to set first parameter as "parameter1" when new method will be called
    
    var param = Expression.Parameter(typeof(string));
    var call = Expression.Call(method, Expression.Constant("parameter1"), param);
    var lambda = Expression.Lambda<Func<string, string>>(call, param);
    var adapter = lambda.Compile();
    // and here i wanna pass only one agrument - second (parameter2)
    var result = adapter("parameter2");
    

    Of course I'm going to assume you have a real use-case for doing that dynamically. Otherwise you could just write:

    Func<string, string> adapter = p => Method("parameter1", p);