[英]Fields Initilizers (Static or not) and Constructor (Static or not) which one runs first
Something is not clear to me, according to what I read: 根据我阅读的内容,我不清楚:
Field Initializers
run before Constructors. Field Initializers
在构造函数之前运行。 Static
field Initializers
execute before the static
constructor
is called (which is still compatible with point 1.). Static
field Initializers
在调用static
constructor
之前执行(仍然与第1点兼容)。 field Initializers
will execute before the type being used (as I understand : not being instantiated but rather being used) field Initializers
(据我所知:不是被实例化而是被使用) This example explains : 这个例子说明:
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);
}
}
This Code Prints 0, then 3 ! 此代码先打印0,然后打印3! How could that be possible?
那怎么可能呢? When we use Foo by doing Foo.X the two first initializers are called, before the constructor (that's ok so far), when
当我们通过执行Foo.X来使用Foo时,在构造函数之前(到目前为止还可以)调用两个第一个初始化程序:
public static Foo Instance = new Foo();
is executed it should run its own 2 initializers before calling the constructor (Point 1) whereas it runs the constructor first and prints X with 0 as a default value. 被执行后,它应该在调用构造函数之前(第1点)运行自己的2个初始化程序,而它首先运行构造函数并以默认值0输出X。
I can't really follow the logic on this, please clarify to me. 我不能真正遵循此逻辑,请向我澄清。
Edit : what I expect to happen : 编辑:我期望发生的事情:
If a type has no static constructor, field Initializers will execute before the type being used (as I understand : not being instantiated but rather being used)
如果一个类型没有静态构造函数,则将在使用该类型之前执行字段初始化程序(据我所知:不是被实例化而是被使用)
Not necessarily. 不必要。
If there is no static constructor, then static field initializers will be executed at some time before a static field is first used - but the static field initializers don't have to execute before any instances are created. 如果没有静态构造函数,则静态字段初始化将在静态字段前一段时间被执行第一次使用-但静态字段初始没有被创建的所有实例之前执行。
From the C# 5 specification section 10.5.5.1: 根据C#5规范的第10.5.5.1节:
The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration.
类的静态字段变量初始值设定项对应于以文本顺序执行的分配序列,这些赋值序列出现在类声明中。 If a static constructor (§10.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor.
如果类中存在静态构造函数(第10.12节),则在执行该静态构造函数之前立即执行静态字段初始化程序。 Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.
否则,将在首次使用该类的静态字段之前,在与实现相关的时间执行静态字段初始化程序。
But in your case, you're just seeing that when the constructor of Foo
is called in order to initialize Instance
, X
is still 0, because it hasn't been assigned a value. 但是在您的情况下,您只是看到调用
Foo
的构造函数以初始化Instance
, X
仍为0,因为尚未为其分配值。 The field initializers are executed in textual order, so Instance
is assigned a value before X
. 字段初始值设定项是按文本顺序执行的,因此在
X
之前为Instance
分配了一个值。 It's as simple as that - it's not a matter of timing between static fields and instance fields, as you haven't got any instance fields. 它是那样简单-它不是静态字段和实例字段之间的时序的问题,因为你没有得到任何实例字段。
EDIT: It seems that you're being getting confused by the constructor call. 编辑:似乎您对构造函数调用感到困惑。
Foo
is already being initialized - the constructor call doesn't change that, and there's no "second initialization". Foo
已经被初始化-构造函数调用不会更改它,并且没有“第二次初始化”。 The constructor is called normally, prints "0" and then returns. 构造函数通常被调用,显示“ 0”,然后返回。 Then
X
is assigned a value of 3. 然后为
X
分配值3。
Foo()
constructor is not a static constructor, hence its not run first as in with your case 3
. Foo()
构造函数不是静态构造函数,因此它不会像您的case 3
一样首先运行。
Hence, the fields are first initialized from top to bottom. 因此,首先从上到下初始化字段。
When static Foo
is first initialized, it is executed and that is what prints 0
, then when X
is initialized, that's what is printed with System.Console.WriteLine()
call. 第一次
static Foo
初始化时,将执行它,然后显示0
;然后,当X
初始化时,即使用System.Console.WriteLine()
调用来打印。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.