发出默认构造函数调用
本文关键字:函数调用 默认 | 更新日期: 2023-09-27 18:03:47
我在运行时生成新的类型,在生成默认构造函数之后,我想要生成另一个带参数的构造函数。我是这样做的:
cb = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
CallingConventions.Standard, new Type[] { typeof(bool) });
GenConstructorWithParameters(cb, fields, genFields);
问题是,我无法从方法GenConstructorWithParameters调用默认构造函数,因为CLR不允许我写这样的东西:
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Call, cb.DeclaringType.GetConstructor(Type.EmptyTypes));//Not allowed to call .GetConstructor() on not created type!
如何发出对默认构造函数的调用?这可能吗?
tb - instance of TypeBuilder
, cb - ConstructorBuilder
您应该将当前的ConstructorBuilder
传递给默认构造函数,而不是使用DeclaringType.GetConstructor
。
基本上,在构建类型时,在可能对现有类型使用基于反射的方法的地方,您应该传递已经使用的构建器。
所以应该是:
gen.Emit(OpCodes.Call, defaultCB);
defaultCB
是您在定义默认构造函数时声明的ConstructorBuilder
。你想要newobj
:
gen.Emit(OpCodes.Newobj, cb.DeclaringType.GetConstructor(Type.EmptyTypes));
Dim objCtor As ConstructorInfo = objType.GetConstructor(New Type() {})
Dim pointCtor As ConstructorBuilder = pointTypeBld.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ctorParams)
Dim ctorIL As ILGenerator = pointCtor.GetILGenerator()
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Call, objCtor)
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_1)
ctorIL.Emit(OpCodes.Stfld, xField)
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_2)
ctorIL.Emit(OpCodes.Stfld, yField)
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_3)
ctorIL.Emit(OpCodes.Stfld, zField)
ctorIL.Emit(OpCodes.Ret)
Dim myDynamicType As Type = Nothing
Dim myDTctor As ConstructorInfo = myDynamicType.GetConstructor(aPtypes)
Console.WriteLine("Constructor: {0};", myDTctor.ToString())