2015-04-13 106 views
4

首先,我想說這是爲了一個大學項目,所以我沒有尋找解決方案,只是幫助理解我做錯了什麼,所以我可以嘗試修理它。Reflection.Emit創建泛型繼承方法

我需要動態創建一個繼承另一個類的類。每個方法都需要調用基本方法,同時添加額外的代碼(在這種情況下,將MethodInfo發送給靜態方法,這樣我就可以計算調用方法的次數)。

什麼,我想要做的一個例子:

public class A 
{ 
    public virtual void M1(B arg0, int arg1) 
    { //do stuff 
    } 
} 

,並動態創建此:

public class InstrA : A 
{ 
    public override void M1(B arg0, int arg1) 
    { 
     base.M1(arg0,arg1) 
     ProfilerCounter.LogMethod(typeof(InstrA).GetMethod("M1")); 
    } 
} 

我能夠做到這一點,除了當有通用的方法......我已經在互聯網上搜索了,閱讀了MSND如何:定義泛型方法等,但無濟於事。

我的代碼來構建方法如下: (編者)

public static void BuildMethod(MethodInfo method, TypeBuilder dest) 
{   
    Type[] param_types = GetParameterTypes(method.GetParameters()); 
    MethodBuilder mb = dest.DefineMethod(
     method.Name, 
     method.Attributes); 

    Type toReturn = method.ReturnType; 

    mb.SetReturnType(toReturn); 
    mb.SetParameters(param_types);   

    //from here I create the IL code, so that it calls base and then adds the methodinfo to a counter 
    //so that everytime the method is run, it will register 
    var getMethodMethod = typeof(MethodBase).GetMethod(
      "GetMethodFromHandle", 
      new[] { typeof(RuntimeMethodHandle) });   

     ILGenerator il_method = mb.GetILGenerator(); 
     il_method.Emit(OpCodes.Ldarg_0); 
     for (int i = 0; i < param_types.Length; i++) 
     { 
      il_method.Emit(OpCodes.Ldarg, i + 1); 
     } 
     il_method.Emit(OpCodes.Call, method); 
     il_method.Emit(OpCodes.Ldtoken, method); 
     il_method.Emit(OpCodes.Call, getMethodMethod); 
     il_method.Emit(OpCodes.Castclass, typeof(MethodInfo));   
     il_method.Emit(OpCodes.Call, typeof(ProfilerCounter).GetMethod("LogMethod")); 
     il_method.Emit(OpCodes.Ret); 

     dest.DefineMethodOverride(mb, method); 
} 

當我試圖創建與TypeBuilder.CreateType()的類型,它拋出一個TypeLoadException,說的簽名正文和方法的聲明不匹配,我設法發現問題是關於通用參數。

但是,我不明白如何解決它。

任何幫助,將不勝感激。

+0

_「創建一個實現另一個類的類」_ - 你的意思是「...那個_inherits_另一個類」?你不能實現另一個班級;它已經被執行。這就是爲什麼它是一個班。至於如何得到四個沒有[很好,_minimal_,_complete_代碼示例](http://stackoverflow.com/help/mcve)的表決清楚地表明問題,我不知道。完全可以說,你的問題中沒有足夠的細節來清晰,有效地回答問題。 –

+0

感謝您的輸入,我已經對代碼和文本做了一些修改,嘗試並更好地解釋我想要的內容。 –

回答

1

好吧,我已經能夠解決我的問題...基本上,我是越來越有MethodBuilder.DefineGenericParameter的含義(..)

反正弄得我下面的代碼添加

MethodBuilder mb = dest.DefineMethod(
    method.Name, 
    method.Attributes); 

if (method.IsGenericMethod) 
{ 
    Type[] genericTypes = method.GetGenericArguments(); 
    foreach (Type t in genericTypes) 
    { 
     mb.DefineGenericParameters(t.Name); 
    } 
} 

mb.SetReturnType(method.ReturnType); 
mb.SetParameters(param_types); 

所以基本上......我沒有在方法構建器中定義我的泛型參數。