IL 发出调用泛型类型构造函数

本文关键字:泛型类型 构造函数 调用 IL | 更新日期: 2023-09-27 18:35:45

我正在尝试使用 Emit 在动态方法中创建一个新的 List<> 对象:

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 实现的代码,这些 OpCode 似乎是正确的,所以我猜这是我在尝试获取泛型类型的构造函数时做错了什么。

我做错了什么,我怎样才能让它工作?

编辑:错误发生在以下行:

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

错误消息:mscorlib 中发生类型为"System.Reflection.TargetInvocationException"的未处理异常.dll

其他信息:目标已引发异常。

内部异常:公共语言运行库检测到无效程序。

堆栈跟踪:在TestObjectProxy..ctor()

IL 发出调用泛型类型构造函数

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

这还不完整。基构造函数调用是对基类的实例方法的常规调用,因此您需要在它之前使用另一个Ldarg_0