实例的创建顺序

本文关键字:顺序 创建 实例 | 更新日期: 2023-09-27 18:34:53

我有以下类:

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();
    } 
}

因此,当我像new Y();那样创建Y实例时,我认为首先创建一个X类型的实例,然后创建一个Y类型的实例,因为X是基类,并且必须首先创建基类而不是其派生类(Y(。

但是,读取反编译代码this存在于base之前,如果应该在this之前创建base,这怎么可能?

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

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

很困惑!

实例的创建顺序

也许它只存在一个对象?

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

  • 如果存在表单 this(...) 的构造函数初始值设定项,则执行该初始值设定项。否则,将执行字段初始值设定项。
  • 调用基类构造函数;请记住,如果根本不指定构造函数初始值设定项,则等效于base()
  • 执行构造函数的主体

没有"base被创造"或"this被创造"的概念。

C# 5 规范的 7.6.10.1 和 10.11 节对此进行了介绍。

C# 编程指南

说(在 Fields(C# 编程指南(中,强调我的(:

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

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