2014-12-29 5 views
2

Я пытаюсь создать новый список <> объекта в динамическом методе с использованием Emit:IL Вызывает генератор типового типа?

Type original; // original is a type passed 

AssemblyName assemblyName = new AssemblyName("CustomAssembly"); 
AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); 
ModuleBuilder _moduleBuilder = assembly.DefineDynamicModule("CustomModule"); 

// - IProxy can be ignored for this example 
TypeBuilder typeBuilder = _moduleBuilder.DefineType(original.Name + "Proxy", TypeAttributes.Public | TypeAttributes.Class, original, new Type[] { typeof(IProxy) }); 

// - Getting the type of List<Interceptor> 
Type interceptorList = typeof(List<>).MakeGenericType(typeof(Interceptor)); 
// - Setting a 'private List<Interceptor> _interceptors;' 
FieldBuilder interceptorField = typeBuilder.DefineField("_interceptors", interceptorList, FieldAttributes.Private); 
// - Getting the default constructor 'new List<Interceptor>()' 
ConstructorInfo interceptorConstructor = interceptorList.GetConstructor(Type.EmptyTypes); 
// - And the '.Add(Interceptor interceptor)' method 
MethodInfo addInterceptor = interceptorList.GetMethod("Add", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(Interceptor) }, null); 

foreach (ConstructorInfo constructorInfo in original.GetConstructors()) 
{ 
    ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.HideBySig, CallingConventions.Standard, parameters); 
    ILGenerator ilGen = constructorBuilder.GetILGenerator(); 
    ilGen.Emit(OpCodes.Ldarg_0); //[this] 

    //These two lines cause an exception when I try to create this custom type   
    ilGen.Emit(OpCodes.Newobj, interceptorConstructor); //[new List<Interceptor>();] 
    ilGen.Emit(OpCodes.Stfld, interceptorField); //[_interceptors = new List<Interceptor>();] 

    // - Calling the base constructor 
    ilGen.Emit(OpCodes.Call, constructorInfo); 
    ilGen.Emit(OpCodes.Ret); 
} 

Я проверил код, который я пытаюсь достичь с помощью ILDASM, и эти Opcodes, кажется, правы , поэтому я предполагаю, что это то, что я делаю неправильно, когда пытаюсь получить конструктор родового типа.

Что я делаю неправильно, как я могу заставить это работать?

Edit: ошибка происходит на этой линии:

// - Type is the custom type created in runtime 
Activator.CreateInstance(Type); 

Сообщение об ошибке: Необработанное исключение типа 'System.Reflection.TargetInvocationException' произошло в mscorlib.dll

Дополнительная информация : Исключение выбрано целью.

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

Трассировка стека: в TestObjectProxy..ctor()

+0

Какая ошибка у вас возникла? – SLaks

+0

@SLaks Отредактировано с сообщением об ошибке (было немного проблем с переводом, впервые увидев это исключение). – Danicco

+0

Отлаживайте и проверяйте свойство 'InnerException' - вы найдете там больше информации. – Haney

ответ

5
// - Calling the base constructor 
ilGen.Emit(OpCodes.Call, constructorInfo); 

Это не полный. Вызов базового конструктора является регулярным вызовом метода экземпляра базового класса, поэтому вам нужно еще один Ldarg_0.

+0

Омг, это имеет смысл, и теперь он работает! Спасибо! – Danicco

 Смежные вопросы

  • Нет связанных вопросов^_^