如何使用reflection来调用方法并在编译时传递类型未知的参数?

我想用一个从字符串输入“解析”的参数值动态调用类的方法

例如:我想用以下命令调用以下程序:

c:> myprog.exe MethodA System.Int32 777
c:> myprog.exe MethodA System.float 23.17
c:> myprog.exe MethodB System.Int32&777
c:> myprog.exe MethodC System.Int32 777 System.String ThisCanBeDone

static void Main(string[] args) { ClassA aa = new ClassA(); System.Type[] types = new Type[args.Length / 2]; object[] ParamArray = new object[types.Length]; for (int i=0; i < types.Length; i++) { types[i] = System.Type.GetType(args[i*2 + 1]); // LINE_X: this will obviously cause runtime error invalid type/casting ParamArray[i] = args[i*2 + 2]; MethodInfo callInfo = aa.GetType().GetMethod(args[0],types); callInfo.Invoke(aa, ParamArray); } 

//在不可更改的类库中:

public class ClassA {public void MethodA(int i){Console.Write(i.ToString()); }

  public void MethodA(float f) { Console.Write(f.ToString()); } public void MethodB(ref int i) { Console.Write(i.ToString()); i++; } public void MethodC(int i, string s) { Console.Write(s + i.ToString()); } public void MethodA(object o) { Console.Write("Argg! Type Trapped!"); } } 

上面代码中的“LINE_X”是粘性部分。 首先,我不知道如何在使用Activator.CreatInstance或其他东西创建它之后如何为int或ref int参数赋值 。 确实会想到typeConverter,但那时还需要显式的编译类型转换。

我是用JavaScript眼镜看CLR还是有办法做到这一点?

试试这个:

 void Main(string[] args) { ClassA a = new ClassA(); System.Type[] types = new Type[(args.Length -1) / 2]; object[] ParamArray = new object[types.Length]; for (int i=0; i < types.Length; i++) { if(args[i*2 + 1].EndsWith("&")) { var type = System.Type.GetType(args[i*2 + 1].Substring(0,args[i*2 +1].Length - 1)); ParamArray[i] = Convert.ChangeType(args[i*2 + 2],type); types[i] = System.Type.GetType(args[i*2 + 1]); } else { types[i] = System.Type.GetType(args[i*2 + 1]); ParamArray[i] = Convert.ChangeType(args[i*2 + 2],types[i]); } } MethodInfo callInfo = typeof(ClassA).GetMethod(args[0],types); callInfo.Invoke(a, ParamArray); 

}

编辑:这应该照顾参考参数

如果你想让ref工作,你需要剥离&转换它:

  static void Main(string[] args) { ClassA a = new ClassA(); int half_arg_length = args.Length / 2; System.Type[] param_types = new Type[half_arg_length]; object[] param_values = new object[half_arg_length]; for (int i = 0; i < half_arg_length; i++) { string string_type = args[i * 2 + 1]; param_types[i] = System.Type.GetType(string_type); Type convert_type = System.Type.GetType(string_type.TrimEnd('&')); param_values[i] = Convert.ChangeType(args[i * 2 + 2], convert_type); } MethodInfo callInfo = typeof(ClassA).GetMethod(args[0], param_types); object res = callInfo.Invoke(a, param_values); }