2 回答
TA贡献1735条经验 获得超5个赞
这是编译器优化的问题,如果你在类外部访问类的公共静态字段,那么这个字段必须在访问前就已经被初始化好,如果你没有静态构造函数,编译器不知道什么时候去初始化这个静态字段,所以编译器只能在主函数之前去初始化这些静态变量。但如果你在类的内部访问类的静态成员,由于类的静态字段在类的公共方法或属性可以执行之前肯定已经初始化好了,所以不需要在主函数前初始化静态字段。
那么你要问了,编译器编译出的代码为什么不能在调用 Class1.str之前先检查一下这个类的静态字段有没有初始化过,如果没初始化,就先初始化。当然是可以的,但这样势必影响静态字段的访问效率,因为每次调用静态字段都要判断是否已经初始化过了。所以编译器出于优化的考虑做了这样的设计。
下面看汇编
有静态构造函数情况下
string s = Class1.str;
00000029 mov edx,25h
0000002e mov ecx,9896BCh
00000033 call FFCA1218
00000038 mov eax,dword ptr ds:[022F98B0h]
0000003d mov edi,eax
在第一次获取Class1.str 前 有一个call FFCA1218 这就是调用静态构造函数。
没有静态构造函数
string s = Class1.str;
00000029 mov eax,dword ptr ds:[022F98B0h]
0000002e mov edi,eax
这时候直接就赋值了,那么只能在主函数进入前初始化静态字段了。
没有静态构造函数,但没有在类以外调用静态字段。
Class1.c();
00000025 call FFCBB410
0000002a nop
直接远程调用 c 方法,但在调用这个方法前程序跳到了初始化静态字段的地方,应该是有个地方去判断类还没有初始化完成,于是先初始化了。编译器优化时应该是认为远程调用方法因为本身就比较耗时,加入一个判断语句过对性能的影响不会很大。
TA贡献1802条经验 获得超5个赞
如果类中包含用来开始执行的 Main 方法,则该类的静态构造函数将在调用 Main 方法之前执行。
任何带有初始值设定项的静态字段,则在执行该类的静态构造函数时,先要按照文本顺序执行那些初始值设定项。
如果没有编写静态构造函数,而这时类中包含带有初始值设定的静态字段,那么编译器会自动生成默认的静态构造函数。
- 2 回答
- 0 关注
- 292 浏览
添加回答
举报