Search code examples
c#expression-treesargumentexception

How to pass runtime argument variable in Expression.Call?


I'm missing something trivial here. Say I have a method like this:

abstract class C
{
    public static void M(Type t, params int[] i)
    {

    }
}

I'm learning expression trees and I need to build a delegate that calls this method with some predefined arguments. The problem is that I don't know to choose the correct overload and pass arguments of Expression.Call.

I want to achieve this:

//I have other overloads for M, hence I need to specify the type of arugments
var methodInfo = typeof(C).GetMethod("M", new Type[] { typeof(Type), typeof(int[]) });

//this is the first argument to method M, not sure if I have chosen the right expression
var typeArgumentExp = Expression.Parameter(someType);

var intArrayArgumentExp = Enumerable.Repeat(Expression.Constant(0), 3);

var combinedArgumentsExp = new Expression[] { typeArgumentExp }.Concat(intArrayArgumentExp);
var call = Expression.Call(methodInfo, combinedArgumentsExp);

At the Expression.Call line I get:

An unhandled exception of type 'System.ArgumentException' occurred in System.Core.dll

Additional information: Incorrect number of arguments supplied for call to method 'Void M(System.Type, Int32[])'

Where have I gone wrong?


Solution

  • I solved it like this (shown here Calling (params object[]) with Expression[]):

    //I have other overloads for M, hence I need to specify the type of arugments
    var methodInfo = typeof(C).GetMethod("M", new Type[] { typeof(Type), typeof(int[]) });
    
    //I fixed this issue where the first argument should be typeof(Type)
    var typeArgumentExp = Expression.Parameter(typeof(Type));
    
    var intArrayArgumentExp = Expression.NewArrayInit(typeof(int), Enumerable.Repeat(Expression.Constant(0), 3));
    
    var combinedArgumentsExp = new Expression[] { typeArgumentExp }.Concat(intArrayArgumentExp);
    var call = Expression.Call(methodInfo, combinedArgumentsExp);
    

    Expression.NewArrayInit does the trick. Thanks hvd for his direction.