2009-09-06 60 views
2

我想动态创建一些方法,它将接受单个参数 - 类A的实例,然后将在传递的A实例中执行方法B. B的参数类型为int。因此,这里的模式:Reflection.Emit动态创建方法

dynamicMethod(A a){ 
a.B(12); 
} 

这里是我的尝试:

DynamicMethod method = new DynamicMethod(string.Empty, typeof(void), new[] { typeof(A) }, typeof(Program)); 
MethodInfo methodB = typeof(A).GetMethod("B", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null); 
ILGenerator gen = method.GetILGenerator(); 

gen.Emit(OpCodes.Nop); 
gen.Emit(OpCodes.Ldarg_0); 
gen.Emit(OpCodes.Ldarg_S, 100); 
gen.Emit(OpCodes.Call, methodB); 

但是编译器告诉我,CLR没有找到方法。你能帮我吗?

+1

您可以考虑使用'System.Linq.Expressions'来代替编译表达式树。这很容易。 – 2009-09-06 03:09:15

回答

1

MSDN约the types parameter of the Type.GetMethod function

表示的数量,顺序和类型的参数的方法来获取类型对象的数组。

您传递一个空数组,指示“不带参数的方法”。但正如你所说的,“B有[int]类型的参数。”

这将工作:

MethodInfo methodB = typeof(A).GetMethod(
      "B", 
      BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, 
      null, 
      new Type[] { typeof(int) } 
      , null); 

如果我理解正确Ldarg_S将加载方法的百分之一周的说法,similiarly到Ldarg_0:

gen.Emit(OpCodes.Ldarg_S, 100); 

对于加载一个恒定值使用Ldc_I4

gen.Emit(OpCodes.Ldc_I4, 100); 
+0

是的,对,但我应该如何通过Emit方法传递这个参数?我应该使用哪种OpCode? – 2009-09-06 17:55:41