字段Initilizers(静态或非静态)和构造函数(静态或非静态)首先运行

时间:2014-02-02 18:25:50

标签: c# .net visual-studio constructor initializer

根据我所读到的,我不清楚某些事情:

  1. Field Initializers在Constructors之前运行。
  2. Static field Initializers在调用static constructor之前执行(仍然与第1点兼容。)。
  3. 如果某个类型没有静态构造函数,field Initializers将在使用的类型之前执行(据我所知:未实例化,而是被使用)
  4. 这个例子解释了:

    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。

    我无法真正遵循这一逻辑,请向我澄清。

    编辑:我期望发生的事情:

    1. 当Foo.X:执行时:public static Foo Instance = new Foo();
    2. 在调用打印的构造函数之前("在构造函数中:" + X),public static int X = 3;应该执行,但是构造函数首先触发,是不是认为字段首先完成运行?我的意思是即使在跳入内部创建新的Foo实例时,也必须先运行字段。
    3. 从最后两点我打算打印3然后3

2 个答案:

答案 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>