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;
}
在需要时按类型初始化(不考虑beforeldinit)。带类:"文本顺序":
ECMA 334:中的§17.11
如果一个类包含任何带有初始化器的静态字段,那么这些初始化器将在执行静态构造函数之前立即按文本顺序执行。
它不适用于实例字段,因为不能在字段初始值设定项中使用实例值。
这一切都很有意义。以下是事件序列:
- 您呼叫
A.t
- 由于这是
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
的默认值
- 由于这是
- 静态初始化的顺序继续,将
A.c
设置为3
- 现在
A
已准备好使用,并且t()
根据存储在A
和B
的相应字段中的值继续打印2 2 3
如果我是你,我总是假设你的编译器以随机(未知)顺序初始化变量。
顺便说一下,static
变量与您的类相关联,而不是与类的任何实例相关联。它们本质上是全局变量。
初始化按照它在类中出现的顺序进行。这就是这里发生的事情:
- A已初始化。它开始设置A.A,但需要B,所以
- B被初始化。B.B被设置-A.c是有效的,但还没有初始化,所以它是0。B.B变为2
- A.A被设置为B.B(2)+c(它还没有被设置,所以为0)。A.A现在是2岁
- 最后,c被设置为3
-编辑-我知道我使用了静态,但请解释非静态。我将在一分钟内用非静态进行测试
非静态字段没有这个问题,因为您无法读取尚未构造的对象的实例字段。