c# - C# 中静态类初始化的顺序是确定性的吗?

标签 c# static deterministic

我做了一些搜索,我认为以下代码可以保证产生输出:

B.X = 7

B.X = 0

A.X = 1

A = 1, B = 0
static class B
{
    public static int X = 7;
    static B() {
        Console.WriteLine("B.X = " + X);
        X = A.X;
        Console.WriteLine("B.X = " + X);
    }
}

static class A
{
    public static int X = B.X + 1;
    static A() {
        Console.WriteLine("A.X = " + X);
    }
}

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

我已经运行了无数次,并且总是在代码部分上方获得输出;我只是想验证它会改变吗?即使在文本上,类 A 和类 B 被重新排列?

是否保证静态对象的第一次使用会触发其静态成员的初始化,然后再实例化其静态构造函数?对于这个程序,在main中使用A.X会触发A.X的初始化,进而初始化B.X,然后是B() 并在完成A.X 的初始化后,将继续执行A()。最后,Main() 将输出 A.X 和 B.X`。

最佳答案

直接来自 ECMA-334:

17.4.5.1: "If a static constructor (§17.11) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class."

和:

17.11: The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

  • An instance of the class is created.
  • Any of the static members of the class are referenced.

If a class contains the Main method (§10.1) in which execution begins, the static constructor for that class executes before the Main method is called. If a class contains any static fields with initializers, those initializers are executed in textual order immediately prior to executing the static constructor (§17.4.5).

所以顺序是:

  • A.X 使用了,所以调用了 static A()
  • A.X需要初始化,但是它使用了B.X,所以调用了static B()
  • B.X需要初始化,初始化为7。B.X = 7
  • B 的所有静态字段都已初始化,因此调用了static B()X 被打印(“7”),然后它被设置为 A.XA已经开始初始化,所以我们得到A.X的值,这是默认值(“当一个类被初始化时,该类中的所有静态字段首先被初始化初始化为它们的默认值"); B.X = 0,并打印 ("0")。
  • 完成初始化BA.X 的值设置为B.X+1A.X = 1
  • A 的所有静态字段都已初始化,因此调用了static A()A.X 被打印出来(“1”)。
  • 返回 Main,打印 A.XB.X 的值(“1”、“0”)。

它实际上在标准中对此进行了评论:

17.4.5: It is possible for static fields with variable initializers to be observed in their default value state. However, this is strongly discouraged as a matter of style.

关于c# - C# 中静态类初始化的顺序是确定性的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3681055/

相关文章:

c - 在函数中静态标识的数组

c# - 在方法内返回await fooAsync()或return fooAsync()

c# - jQuery可拖动图像,鼠标越界时停止拖动(div)

c# - 如何将 vector<double> 从 C++ 编码到 C#

coq - 如何证明偏序归纳谓词的可判定性?

deterministic - 如果一种语言 (L) 被 n 状态 NFA 识别,它是否也能被状态不超过 2^n 的 DFA 识别?

c++ - 仅在 boost::hash_combine 中运行一个程序期间保证确定性

c# - Xamarin.iOS 应用程序中的 UIApplication 断言失败

c++ - 编译器可以优化在堆上分配静态数组的内存管理吗?

无法使用实例引用访问 C# 成员