C# 字段Initilizers(静态或非静态)和构造函数(静态或非静态),其中一个先运行
根据我所读到的,有些事情我不清楚:C# 字段Initilizers(静态或非静态)和构造函数(静态或非静态),其中一个先运行,c#,.net,visual-studio,constructor,initializer,C#,.net,Visual Studio,Constructor,Initializer,根据我所读到的,有些事情我不清楚: 字段初始值设定项在构造函数之前运行 静态字段初始值设定项在调用静态构造函数之前执行(该构造函数仍与第1点兼容) 如果一个类型没有静态构造函数,字段初始值设定项将在使用该类型之前执行(据我所知:不是实例化而是使用) 本例说明: class Program { static void Main(string[] args) { Console.WriteLine(Foo.X); Console.ReadLine();
字段初始值设定项在构造函数之前运行
静态
字段初始值设定项
在调用静态
构造函数
之前执行(该构造函数仍与第1点兼容)字段初始值设定项将在使用该类型之前执行(据我所知:不是实例化而是使用)
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Foo.X);
Console.ReadLine();
}
}
class Foo
{
public static Foo Instance = new Foo();
public static int X = 3;
Foo()
{
Console.WriteLine("In constructor: " + X);
}
}
这段代码打印0,然后打印3!这怎么可能呢?当我们通过执行Foo.X来使用Foo时,在构造函数(到目前为止还可以)之前调用两个初始值设定项,当
在调用构造函数(第1点)之前,它应该运行自己的2个初始值设定项,而它首先运行构造函数并以0作为默认值打印X
我真的无法理解这个逻辑,请向我澄清
编辑:我期望发生的事情:
Foo()
因此,首先从上到下初始化字段
当static Foo
第一次初始化时,它被执行,这就是打印0
的内容,然后当X
被初始化时,这就是使用System.Console.WriteLine()调用打印的内容
如果一个类型没有静态构造函数,字段初始值设定项将在使用该类型之前执行(据我所知:不是实例化而是使用)
不一定
如果没有静态构造函数,那么静态字段初始值设定项将在首次使用静态字段之前的某个时间执行-但是静态字段初始值设定项不必在创建任何实例之前执行
根据C#5规范第10.5.5.1节:
类的静态字段变量初始值设定项对应于按文本顺序执行的赋值序列,在类声明中以文本顺序出现。如果类中存在静态构造函数(§10.12),则在执行该静态构造函数之前立即执行静态字段初始值设定项。否则,静态字段初始值设定项将在第一次使用该类的静态字段之前的依赖于实现的时间执行
但是在您的例子中,您刚刚看到当调用Foo
的构造函数来初始化实例时,X
仍然是0,因为它没有被赋值。字段初始值设定项是按文本顺序执行的,因此在X
之前为Instance
分配一个值。就这么简单-这不是静态字段和实例字段之间的时间问题,因为您没有任何实例字段
编辑:看来你被构造函数调用搞糊涂了Foo
已被初始化-构造函数调用不会改变这一点,并且没有“第二次初始化”。构造函数被正常调用,打印“0”,然后返回。然后X
被赋值为3。问题是,当调用Foo.X时,它会从上到下执行,当从上到下执行时,它会遇到公共静态Foo Instance=new Foo();它从下到上运行,如果不是,它将永远不会打印0,可能是我,我没有真正捕获它从上到下,static Foo Instance
初始化时调用构造函数,请记住,在未遇到static int X
之前,X
仍然是0
。然后在初始化实例
之后,它还将X
的值分配给3
。然后打印到控制台@AymenDaoudi知道字段初始值设定项是按文本顺序执行的,因此实例在X之前被赋值,问题是当它被赋值(意味着调用构造函数)时,它在将3赋值到X之前就完成了,这怎么可能(第1点)。@AymenDaoudi:它不-它打印0。在执行所有静态初始值设定项后,当打印Foo.X
时,仅打印3#为了更清楚,将构造函数中的代码更改为:Console.WriteLine(“构造函数中:+X”)代码>。现在还不清楚您预期会发生什么,但是当您在Foo
类型初始值设定项中调用Foo
的构造函数时,类型初始值设定项已经在运行,因此不会再次单独运行。很抱歉,我可能理解得很慢,我更新了问题,解释了我的想法expect@AymenDaoudi:您说过希望在构造函数执行之前执行X=3
,但不是为什么。在构造函数完成之前,Instance
的赋值无法完成,这发生在X=3
赋值之前。请注意,这里的两个字段都是静态字段-您看到的只是静态字段初始值设定项调用构造函数的副作用,从而允许查看另一个静态字段的默认值。Thx Jon我现在明白了
public static Foo Instance = new Foo();