IL,发出默认构造函数调用

4

我正在运行时生成新的类型,生成默认构造函数后,我想再生成一个带参数的构造函数。我的做法是:

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 - TypeBuilder的实例,cb - ConstructorBuilder

抱歉,不是重复内容。 :) - leppie
3个回答

4

不要使用DeclaringType.GetConstructor,而是应该将当前的ConstructorBuilder传递给默认构造函数。

基本上,在构建类型时,在可能使用现有类型的反射方法的地方,应该改为传入已经在使用的构建器。


因此,代码应该是这样的:

gen.Emit(OpCodes.Call, defaultCB);

其中defaultCB是您在定义默认构造函数时声明的ConstructorBuilder


@taras.roshko - 我相信了Marc的答案,但我现在已经恢复到使用“Call”了,因为我刚刚编写了一些代码并在反射器中进行了检查。 - Damien_The_Unbeliever
“gen”是什么鬼? - Bruno Santos
@BrunoSantos - 它取决于OP在他们的问题中已经有了什么。然而,从上下文来看,一个相当好的猜测是它是ILGenerator类的一个实例,因为这个类有很多Emit方法定义在它上面。 - Damien_The_Unbeliever

4
您想要使用 newobj
gen.Emit(OpCodes.Newobj, cb.DeclaringType.GetConstructor(Type.EmptyTypes));

同样的NotSupportedException("在类型创建之前,所调用的成员不受支持。") - illegal-immigrant
@taras - 然后保留你之前创建的 ConstructorBuilder。 - Marc Gravell

0
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())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接