【发布时间】:2016-03-11 11:07:29
【问题描述】:
关于static fields / constructors,我一直想知道一件事。
static class 在第一次引用它的一个字段时初始化,这很容易。
但是 CLR 怎么知道这是第一次呢?
【问题讨论】:
标签: c# .net clr cil static-initialization
关于static fields / constructors,我一直想知道一件事。
static class 在第一次引用它的一个字段时初始化,这很容易。
但是 CLR 怎么知道这是第一次呢?
【问题讨论】:
标签: c# .net clr cil static-initialization
【讨论】:
static class在第一次引用其中一个字段时初始化,这很容易。
不,没那么简单。忽略方法调用,如果没有标记beforefieldinit,则必须在第一次访问其中一个字段之前初始化static 类。如果它被标记为beforefieldinit,则可以比它更早地初始化。 (Jon Skeet 有an article with lots more information about beforefieldinit。)
这对何时检查类初始化有何影响?由于 CLR 使用 JIT 编译,因此它会在 JIT 编译方法时检查类初始化。如果该类标记为beforefieldinit 并且尚未初始化,则 JIT 编译器会立即对其进行初始化。然后它实际编译该方法,它可以假定该类已经被初始化,因此不需要检查。
如果没有beforefieldinit,如果类还没有被初始化,JIT 编译器必须在每次潜在的第一个字段访问之前发出检查初始化的代码。但如果该类已经初始化并且正在 JIT 编译另一个方法,则 JIT 编译器不必再在那里发出检查。
在某些情况下,这可能会对性能产生负面影响。从上面可以清楚地看出,为了防止这种情况,您需要确保有问题的类被标记为beforefieldinit。从 C# 中做到这一点的方法是没有 static 构造函数,只使用 static 字段初始化器。
【讨论】: