为什么CLR通过初始化优化掉未使用的静态字段?

Jan*_*Jan 5 .net c# optimization initialization static-members

我们有两个代码片段:

A:

public class Foo
{
    private static Bar _unused = new Bar();
}
Run Code Online (Sandbox Code Playgroud)

B:

public class Foo
{
    private static Bar _unused;

    static Foo()
    {
        _unused = new Bar();
    }
}
Run Code Online (Sandbox Code Playgroud)

在情况A中,CLR甚至不会调用Bar ctor(除非它是调试版本或附加调试器),但是在情况B中它在所有情况下都被调用.

问题是,在Bar构造函数中,可以进行调用,使其可以从其他地方访问 - 最常见的是事件订阅.

所以:

  • 为什么案例AB的评估方式不同?
  • 为什么CLR在案例A中根本没有调用Bar ctor - 因为在ctor完成并且实例被分配到适当的字段之前它不应该将其评估为垃圾?

Cod*_*ter 7

如果您不创建构造函数:

类的静态字段变量初始值设定项对应于以它们出现在类声明中的文本顺序执行的赋值序列.如果类中存在静态构造函数(第10.11节),则在执行该静态构造函数之前立即执行静态字段初始值设定项.否则,静态字段初始化器在第一次使用该类的静态字段之前的实现相关时间执行.

如果你有一个静态构造函数:

静态构造函数用于初始化任何静态数据,或执行仅需要执行一次的特定操作.在创建第一个实例或引用任何静态成员之前自动调用它.