문제

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?

도움이 되었습니까?

해결책

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.

다른 팁

The params keyword does not do anything at runtime. When you call C.M(t, 1, 2, 3), the compiler transforms this to C.M(t, new int[] { 1, 2, 3 }). In this case, you are performing parts of the job of the compiler, and this is one transformation that becomes your responsibility. You should explicitly create the array, and call C.M with exactly two arguments.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top