问题描述
ECMA CLI规范在initobj
CLI指令的描述中具有以下语句:
“如果 typeTok 是值类型,则在执行此指令后,实例就可以调用构造函数方法了。”
但是,以下C#代码(其中S
是一个结构):
S s = default;
S s2 = new S();
S s3 = new S(5);
编译为如下所示的IL:
IL_0001: ldloca.s s
IL_0003: initobj S
IL_0009: ldloca.s s2
IL_000b: initobj S
IL_0011: ldloca.s s3
IL_0013: ldc.i4.5
IL_0014: call instance void S::.ctor(int32)
我的问题是,编译器何时会使用initobj
并随后调用值类型的构造函数?
解决方法
如果typeTok是值类型,则在执行此指令后,实例就可以调用构造方法了。
这意味着构造函数可以在此指令后调用构造函数。
但是,正如您在上面的注释中所提到的,由于方法sig上的localsinit
标志,因此无需在构造函数之前再次初始化本地变量。
我的问题是,编译器何时会使用
initobj
并随后调用值类型的构造函数?
我只能找到一种情况,要求编译器使用initobj
,告诉编译器不要使用localsinit
标志。
到目前为止,SkipLocalsInitAttribute应该可以帮助您重现此案,但尚未启动此编译器功能的实施。