根据我所读到的,我不清楚某些事情:
Field Initializers
在Constructors之前运行。Static
field Initializers
在调用static
constructor
之前执行(仍然与第1点兼容。)。field Initializers
将在使用的类型之前执行(据我所知:未实例化,而是被使用)这个例子解释了:
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时,会在构造函数之前调用两个第一个初始化器(到目前为止还可以),
public static Foo Instance = new Foo();
执行它应该在调用构造函数(Point 1)之前运行它自己的2个初始值设定项,而它首先运行构造函数并打印X作为默认值为0。
我无法真正遵循这一逻辑,请向我澄清。
编辑:我期望发生的事情:
答案 0 :(得分:5)
如果某个类型没有静态构造函数,则字段Initializers将在使用的类型之前执行(据我所知:未实例化,而是被使用)
不一定。
如果没有静态构造函数,那么静态字段初始值设定项将在首次使用静态字段之前的某个时间执行 - 但静态字段初始值设定项不必须在创建任何实例之前执行。
来自C#5规范部分10.5.5.1:
类的静态字段变量初始值设定项对应于按照它们出现在类声明中的文本顺序执行的赋值序列。如果类中存在静态构造函数(第10.12节),则在执行该静态构造函数之前立即执行静态字段初始值设定项。否则,静态字段初始值设定项在首次使用该类的静态字段之前的实现相关时间执行。
但是在你的情况下,你只是看到当Foo
的构造函数被调用以初始化Instance
时,X
仍为0,因为它还没有分配了一个值。字段初始值设定项以文本顺序执行,因此Instance
会在X
之前分配一个值。就这么简单 - 这不是静态字段和实例字段之间的时间问题,因为你没有得到任何实例字段。
Foo
已经被初始化 - 构造函数调用不会改变它,并且没有“第二次初始化”。正常调用构造函数,打印“0”然后返回。 然后 X
被赋值为3。
答案 1 :(得分:0)
Foo()
构造函数不是静态构造函数,因此它不会像使用case 3
那样先运行。
因此,首先从上到下初始化字段。
首次初始化static Foo
时,会执行该操作,然后打印0
,然后在X
初始化时,这是System.Console.WriteLine()
调用打印的内容。< / p>