2014-02-14 2 views
0

У меня есть следующий класс: (FYI: Я не могу изменить базовый класс)Как назвать общий базовый метод с TypeBuilder

public abstract class BaseClass 
{ 
    protected TOutput Convert<TInput, TOutput>(TInput input) 
    { 
     return (TOutput)System.Convert.ChangeType(input, typeof(TOutput)); 
    } 
} 

И то, что я пытаюсь построить, это динамический тип как это:

public class DynamicClass : BaseClass 
{ 
    public string Convert(int value) 
    { 
     return base.Convert<int, string>(value); 
    } 
} 

метод, который я использую для построения динамического типа, выглядит следующим образом:

private MethodBuilder BuildConvertMethod(TypeBuilder typeBuilder) 
{ 
    var baseConvertMethod = typeof(BaseClass).GetMethod("Convert", BindingFlags.NonPublic | BindingFlags.CreateInstance | BindingFlags.Instance); 
    var baseConvertMethodInstance = baseConvertMethod.MakeGenericMethod(typeof(int), typeof(string)); 

    var convertMethodBuilder = typeBuilder.DefineMethod("Convert", MethodAttributes.Public, typeof(string), new[] { typeof(int) }); 

    var convertMethodILGenerator = convertMethodBuilder.GetILGenerator(); 
    convertMethodILGenerator.Emit(OpCodes.Nop); 
    convertMethodILGenerator.Emit(OpCodes.Ldarg_0); 
    convertMethodILGenerator.Emit(OpCodes.Ldarg_1); 
    convertMethodILGenerator.Emit(OpCodes.Call, baseConvertMethodInstance); 
    convertMethodILGenerator.Emit(OpCodes.Ldloc_0); 
    convertMethodILGenerator.Emit(OpCodes.Ret); 

    return convertMethodBuilder; 
} 

создание типа Succ eeds. Но когда я создаю экземпляр DynamicClass, а затем вызывает метод Convert я получаю следующее исключение:

System.Reflection.TargetInvocationException: Исключение было брошенный целью вызова. ----> System.InvalidProgramException: Common Language Runtime обнаружил недопустимую программу.

Может кто-нибудь, пожалуйста, помогите мне с этой проблемой?

ответ

0

Call инструкции нажимают на возвращаемое значение в стеке, чтобы вы могли сразу позвонить Ret.

var convertMethodILGenerator = convertMethodBuilder.GetILGenerator(); 
convertMethodILGenerator.Emit(OpCodes.Ldarg_0); 
convertMethodILGenerator.Emit(OpCodes.Ldarg_1); 
convertMethodILGenerator.Emit(OpCodes.Call, baseConvertMethodInstance); 
convertMethodILGenerator.Emit(OpCodes.Ret); 
+0

Большое спасибо. Это сработало сразу. :-) –