静态字段初始化说明及其要求

时间:2014-12-09 09:55:29

标签: c# static static-constructor

在查看了与此相关的许多复杂问题后,我想询问以下具有静态字段初始化的代码的解释。我想知道的另一件事是静态字段初始化的要求。在哪些情况下它会有所帮助??

using System;

class Test
{
    static void Main()
    {
        Console.WriteLine("{0} {1}", B.Y, A.X);
    }

    public static int F(string s)
    {
        Console.WriteLine(s);
        return 1;
    }
}

class A
{
    static A()
    { }

    public static int X = Test.F("Init A");
}

class B
{
    static B()
    { }

    public static int Y = Test.F("Init B");
}

输出:

  

初始B

     

初始A

     

1 1

当没有静态构造函数时,输出可能会有所不同。我无法理解它背后的基本原理。静态字段初始化给这个片段带来了什么区别?有人可以请帮助。我是c#的新手。

1 个答案:

答案 0 :(得分:4)

当类型具有静态构造函数时,运行时被约束为在第一次使用该类型的任何成员之前立即执行所有类型初始化。

当它没有静态构造函数时,运行时具有更大的自由度 - 它必须在第一次使用静态字段之前或构造实例之前的某个时刻执行类型初始化程序,但是&# 39;全部。您甚至可以观察静态方法,这些方法在没有执行类型初始化程序的情况下不接触正在执行的静态字段。

在您的情况下,AB都有静态构造函数,对成员的访问顺序首先是B,然后是A,因此是输出。如果没有那些静态构造函数,您仍然可以保证得到" 1 1"作为最后一行,你仍然得到两个"初始A"和"初始B",但它们的排序不会得到保证。

这就是指定语言和运行时的方式 - 通常它没有影响,因为通常类型初始值设定项只是设置类型,没有其他副作用。理想情况下,类型初始值设定项应该尽可能少 - 如果由于某种原因它们失败,那么类型永远不会可用;类型初始值设定项不会重试。

有关详细信息,请参阅我的beforefieldinit article.NET 4.0 type initializer changes博文。