我想使用从字符串输入中“解析”的参数值动态调用类的方法。
例如: 我想用这些命令调用以下程序:
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);
}
//在不可变的classlib中:
公共类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”是粘性部分。首先,我不知道如何为int或ref int参数赋值,即使我使用Activator.CreatInstance或其他东西创建它。确实会想到typeConverter,但那时还需要显式的编译类型转换。
我是用JavaScript眼镜看CLR还是有办法做到这一点?
答案 0 :(得分:3)
试试这个:
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);
}
编辑:这应该照顾参考参数
答案 1 :(得分:1)
你需要脱掉&amp;如果你想让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);
}