创建实例的顺序

时间:2016-02-17 09:17:55

标签: c#

我有以下课程:

class X
{
    int x = 100;
}

class Y:X
{
    int y = 100;
}

以及以下反编译代码:

class X
{
    int32 x;

    public void X()
    {
       this.x = 100;
       base.Object();
    }
}

class Y:X
{
    int32 y;

    public void Y()
    {
       this.y = 100;
       base.X();
    } 
}

所以当我在Y中创建new Y();的实例时,我认为首先创建一个X类型的实例,然后创建一个Y类型的实例,因为{ {1}}是基类,必须首先创建基类,而不是其派生类(X)。

然而,在Y之前阅读已反编译的代码this,如果base之前应创建base,那么该怎么可能?

也许它只存在一个对象?我们必须始终首先调用基类构造函数来初始化目的吗?

实际上,如果我们不能首先创建该类型的实例,那么调用第一个基类构造函数的理由是什么?

很困惑!

2 个答案:

答案 0 :(得分:5)

  

也许它只存在一个对象?

是的,确切地说。创建单个对象,立即属于指定的类型(在本例中为Y)。所有字段(跨继承层次结构)最初都设置为其相应类型的默认值。创建单个对象,然后使用构造函数初始化。从最派生的类开始,执行指定的构造函数:

  • 如果有this(...)形式的构造函数初始值设定项,则执行该初始值设定项。否则,将执行字段初始值设定项。
  • 调用基类构造函数;请记住,如果您根本没有指定构造函数初始值设定项,则相当于base()
  • 执行构造函数的主体

不知道" base正在创建"或" this被创建"。

这在C#5规范的7.6.10.1和10.11节中有所描述。

答案 1 :(得分:1)

C#编程指南(在Fields (C# Programming Guide)中强调我的):

  

在调用对象实例的构造函数之前,字段会立即初始化。

因此,在完成任何其他操作之前(甚至是基本构造函数调用),字段变量都会被初始化。