1

我在这里遗漏了一些微不足道的东西。假设我有这样的方法:

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

    }
}

我正在学习表达式树,我需要构建一个使用一些预定义参数调用此方法的委托。问题是我不知道选择正确的重载并传递Expression.Call.

我想实现这一点:

//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);

Expression.Call我得到的那一行:

System.Core.dll 中出现“System.ArgumentException”类型的未处理异常

附加信息:为调用方法 'Void M(System.Type, Int32[])' 提供的参数数量不正确

我哪里出错了?

4

2 回答 2

4

关键字在params运行时不做任何事情。当您调用C.M(t, 1, 2, 3)时,编译器会将其转换为C.M(t, new int[] { 1, 2, 3 }). 在这种情况下,您正在执行编译器的部分工作,这是您负责的一种转换。您应该显式创建数组,并C.M使用两个参数进行调用。

于 2013-04-26T15:47:18.923 回答
2

我像这样解决了它(这里显示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可以解决问题。感谢 hvd 的指导。

于 2013-04-26T16:35:31.213 回答