2015-04-13 2 views
4

Во-первых, я хочу сказать, что это для проекта колледжа, поэтому я не ищу решение, а просто помощь в понимании того, что я делаю неправильно, поэтому я могу попытаться почини это.Reflection.Emit Create Generic Inherithed Methods

Я должен динамически создавать класс, который наследует другой класс. Ожидается, что каждый метод вызовет базовый метод, добавив дополнительный код (в этом случае, чтобы отправить 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 How To: Определите общий метод и т. д., но безрезультатно.

Мой код для создания метода состоит в следующем: (Edited)

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, говоря, что сигнатуру тело и объявление метода не совпадают, и мне удалось обнаружить, что проблема связана с параметром Generic.

Однако я не могу понять, как это исправить.

Любая помощь будет оценена по достоинству.

+0

_ "создать класс, который реализует другой класс" _ - вы имеете в виду "... что _inherits_ другого класса"? Вы не можете _implement_ другого класса; это уже реализовано. Вот почему это класс. Что касается того, как вы получили четыре голосов без [хорошего, _minimal_, _complete_ code example] (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); 

Так что в основном ... Я не определял свои общие параметры в методу-строителе.