我在这里遗漏了一些微不足道的东西。说我有这样的方法:
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.ArgumentException'类型的未处理异常 System.Core.dll
附加信息:提供的参数数量不正确 调用方法'Void M(System.Type,Int32 [])'
我哪里出错了?
答案 0 :(得分:4)
params
关键字在运行时不执行任何操作。当您调用C.M(t, 1, 2, 3)
时,编译器会将其转换为C.M(t, new int[] { 1, 2, 3 })
。在这种情况下,您正在执行编译器的部分工作,这是一个成为您的责任的转换。您应该显式创建数组,并使用两个参数调用C.M
。
答案 1 :(得分:1)
我解决了这个问题(这里显示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可以解决问题。感谢他的指示。