2009-09-06 95 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