C#中初始化顺序的规则是什么

本文关键字:规则 是什么 顺序 初始化 | 更新日期: 2023-09-27 18:24:56

可能重复:
C#中的静态变量初始化顺序是什么?

为了好玩,我运行了这个代码

我没想到2 2 3。我预期会出现编译器错误(circlur依赖项)或8 5 3

C#中初始化顺序的规则是什么?

-编辑-我试着做了一个非静态的,我得到了我所期望的。为什么b以前是2,现在是5。我不认为我会喜欢这些规则。。。幸运的是,我从来没有做过这样的事,所以我没有遇到任何问题。

using System;
public class Test
{
        public static void Main()
        {
                A.t();
        }
}
class A
{
    static int a = B.b + c;
    public static int c = 3;
    static public void t()
    {
        Console.WriteLine("{0} {1} {2}", a, B.b, c);
    }
}
class B
{
    public static int b = A.c+2;
}

C#中初始化顺序的规则是什么

在需要时按类型初始化(不考虑beforeldinit)。带类:"文本顺序":

ECMA 334:中的§17.11

如果一个类包含任何带有初始化器的静态字段,那么这些初始化器将在执行静态构造函数之前立即按文本顺序执行。

它不适用于实例字段,因为不能在字段初始值设定项中使用实例值。

这一切都很有意义。以下是事件序列:

  1. 您呼叫A.t
  2. 由于这是A的第一次使用,它的静态成员a被初始化为B.b + c
    • 由于这是B的第一次使用,它的静态成员b被初始化为A.c+2。这不是第一次使用A,所以直接读取A.c。由于它还没有被静态初始化,所以它仍然被设置为默认值0。因此CCD_ 13变为2
    • 此时,A的静态初始值设定项将B.b中的2添加到A自己的c中的0,该值仍设置为0的默认值
  3. 静态初始化的顺序继续,将A.c设置为3
  4. 现在A已准备好使用,并且t()根据存储在AB的相应字段中的值继续打印2 2 3

如果我是你,我总是假设你的编译器以随机(未知)顺序初始化变量。

顺便说一下,static变量与您的类相关联,而不是与类的任何实例相关联。它们本质上是全局变量。

初始化按照它在类中出现的顺序进行。这就是这里发生的事情:

  1. A已初始化。它开始设置A.A,但需要B,所以
  2. B被初始化。B.B被设置-A.c是有效的,但还没有初始化,所以它是0。B.B变为2
  3. A.A被设置为B.B(2)+c(它还没有被设置,所以为0)。A.A现在是2岁
  4. 最后,c被设置为3

-编辑-我知道我使用了静态,但请解释非静态。我将在一分钟内用非静态进行测试

非静态字段没有这个问题,因为您无法读取尚未构造的对象的实例字段。