beforefieldinit旗帜做什么?

Emb*_*rja 77 .net cil

beforefieldinit旗帜做什么?当我查看我班级的IL时,我看到了这个标志,但我不知道这个标志实际上在做什么?

Jon*_*eet 123

在这个问题上看到我的文章.

基本上,beforefieldinit意味着"可以在引用任何静态字段之前的任何点初始化类型".理论上,这意味着它可以非常懒惰地初始化 - 如果你调用一个不接触任何字段的静态方法,JIT不需要初始化类型.

在实践中,它意味着类比其他方式更早地初始化- 可以在第一个可能使用它的方法的开头初始化它.有哪些类型比较这已经beforefieldinit应用到它们,其中类型初始化到第一前刚刚发生的实际使用.

所以,假设我们有:

public static void DoSomething(bool which)
{
    if (which)
    {
        FirstType.Foo();
    }
    else
    {
        SecondType.Bar();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果这两种类型都beforefieldinit适用于它们(在C#中默认情况下它们除非类型具有静态构造函数),那么它们将在DoSomething方法开始时初始化(通常 - 不保证).如果他们没有,beforefieldinit那么根据旗帜只会初始化其中一个.

这就是为什么在实现单例模式时使用静态构造函数(甚至是空构造函数!)的常见原因.

  • 我发现使用静态构造函数(即没有beforefieldinit标志的类)会有性能损失.如果经常调用某个类的静态成员,似乎运行时必须在每次调用之前进行额外的检查,以测试该类型是否已经初始化; beforefieldinit避免了这些检查.使用beforefieldinit时,几个基准测试的速度提高了约50%:http://www.codeproject.com/Articles/87991/Dynamic-interfaces-in-any-NET-language (3认同)

Oma*_*riO 6

看起来它将在4.6中更改

https://github.com/dotnet/coreclr/issues/1193

  • Jon 对从 .Net 4.0 开始的类型初始化更改的详细分析 [此处](https://codeblog.jonskeet.uk/2010/01/26/type-in​​itialization-changes-in-net-4-0/)。 (2认同)