提问人:saner 提问时间:2/3/2023 最后编辑:Dmitry Bychenkosaner 更新时间:2/11/2023 访问量:91
C 语言中的静态构造函数和字段初始化顺序#
Static constructors and field initialization order in C#
问:
简而言之,这个来自 C# 的示例说它写了 0 后跟 3,因为“实例化 Foo 的字段初始值设定项在 X 初始化为 3 之前执行”。
class Program {
static void Main() { Console.WriteLine (Foo.X); } // 3
}
class Foo
{
public static Foo Instance = new Foo(); //static field 1
public static int X = 3; //static field 2
Foo() => Console.WriteLine (X); // 0
}
我的问题是,为什么由于静态场 1 产生新的 Foo(产生新的 Foo,产生新的 Foo,等等)而没有进入无限递归?
答:
1赞
pigeonhands
2/3/2023
#1
静态字段和属性在类的所有实例之间共享,并在一个名为的特殊构造函数中初始化,该构造函数在首次引用类时被调用。.cctor
所以编译后的代码类似于
class Foo
{
public static Foo Instance;
public static int X;
.cctor() {
Instance = new Foo();
X = 3;
}
Foo() => Console.WriteLine (X);
}
呼叫流为 -> -> 。Foo::.cctor
Foo::Foo()
Foo:get_X()
因此,没有递归,但在调用时将具有其默认值。X
.cctor
1赞
Dmitry Bychenko
2/4/2023
#2
让我们来看看发生了什么。在类寻址字段之前,必须
初始 化。Foo
static
class Program {
static void Main() {
// Before Foo class is addressed (here Foo.X), Foo must be initialized
Console.WriteLine(Foo.X);
}
}
.Net 将按照类声明中提及的顺序执行此操作:
class Foo
{
// Will be run first
public static Foo Instance = new Foo();
// Will be run second
public static int X = 3;
Foo() => Console.WriteLine(X);
}
- 到目前为止一切顺利,开始初始化
Instance
public static Foo Instance = new Foo();
构造函数调用,打印: 注意,
由于尚未初始化,将被打印。Foo()
X
Foo() => Console.WriteLine (X);
X
0
X
将被初始化,现在是3
初始化现已完成,.Net 已准备好添加 dress 类Foo
Console.WriteLine(Foo.X);
并将打印(注意初始化的第二步)3
上一个:队列的静态初始化
评论