简体   繁体   English

首先运行的字段初始化器(是否静态)和构造函数(是否静态)

[英]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: 根据我阅读的内容,我不清楚:

  1. Field Initializers run before Constructors. Field Initializers在构造函数之前运行。
  2. Static field Initializers execute before the static constructor is called (which is still compatible with point 1.). Static field Initializers在调用static constructor之前执行(仍然与第1点兼容)。
  3. 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) 如果一个类型没有静态构造函数,则将在使用该类型之前执行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 : 编辑:我期望发生的事情:

  1. when Foo.X : execute: public static Foo Instance = new Foo(); 当Foo.X时:执行:公共静态Foo实例= new Foo();
  2. before calling the constructor that prints ("In constructor: " + X), public static int X = 3; 在调用打印的构造函数之前(“在构造函数中:” + X),public static int X = 3; should be executed, but it happens that the constructor fires first, isn't supposed that the fields complete running first ? 应该执行,但是碰巧构造函数首先触发,难道不是字段首先运行完成? I mean even when jumping inside creating a new Foo instance fields must be run first. 我的意思是,即使在跳入内部创建新的Foo实例时,也必须首先运行字段。
  3. From the two last points I expect to print 3 then 3 从最后两个点,我希望先打印3然后3

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的构造函数以初始化InstanceX仍为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM