C # 构造函数执行顺序

在 C # ,当你这样做

Class(Type param1, Type param2) : base(param1)

是先执行类的构造函数,然后调用超类的构造函数,还是先调用基类的构造函数?

69908 次浏览

它将首先调用基构造函数。还要记住,如果没有将 :base(param1)放在构造函数之后,基本的空构造函数将被调用。

基类的构造函数首先被调用。

你的问题有点含糊不清,但我猜你是想问以下几个问题

什么时候调用 XNA 对象的基本构造函数,而不是使用隐含缺省构造函数

这个问题的答案很大程度上取决于您的场景和底层对象。你能不能澄清一下

  • 情况如何
  • TerrainCollision的基对象的类型是什么?

但是,我的最佳答案是,如果您的参数与基类的构造函数的参数一致,那么几乎可以肯定应该调用它。

[编辑: 在我回答这个问题的时间里,这个问题已经完全改变了]。

答案是它首先调用基。

[下面这个老问题的原答案]

您是否在询问什么时候执行构造函数调用的“基”部分?

如果是这样,如果该类派生自另一个具有这个构造函数的类,那么您将“链接”对该构造函数基的调用:

  public class CollisionBase
{
public CollisionBase(Body body, GameObject entity)
{


}
}


public class TerrainCollision : CollisionBase
{
public TerrainCollision(Body body, GameObject entity)
: base(body, entity)
{


}
}

在本例中,TerrainCollision派生自 CollisionBase。通过以这种方式链接构造函数,可以确保使用提供的参数(而不是缺省构造函数)在基类上调用指定的构造函数

命令是:

  • 成员变量初始化为层次结构中所有类的默认值

然后从派生最多的类开始:

  • 对派生最多的类型执行变量初始值设定项
  • 构造函数链可以计算出要调用哪个基类构造函数
  • 初始化基类(递归所有这些:)
  • 这个类中链中的构造函数体将被执行(注意,如果它们与 Foo() : this(...)等链接在一起,可能会有多个构造函数体

注意,在 Java 中,基类是初始化的 之前变量初始化器是运行的。如果您曾经移植过任何代码,这是一个需要了解的重要区别:)

如果你感兴趣的话,我有一个 详情请浏览

构造函数机制要好得多,因为它让应用程序使用构造函数链接,如果要扩展应用程序,它可以通过继承实现最小化代码更改的能力。 Jon Skeets 文章

不确定这是否应该是一个评论/答案,但是对于那些通过例子学习的人来说,这个小提琴也说明了顺序: https://dotnetfiddle.net/kETPKP

using System;


// order is approximately
/*
1) most derived initializers first.
2) most base constructors first (or top-level in constructor-stack first.)
*/
public class Program
{
public static void Main()
{
var d = new D();
}
}


public class A
{
public readonly C ac = new C("A");


public A()
{
Console.WriteLine("A");
}
public A(string x) : this()
{
Console.WriteLine("A got " + x);
}
}


public class B : A
{
public readonly C bc = new C("B");


public B(): base()
{
Console.WriteLine("B");
}
public B(string x): base(x)
{
Console.WriteLine("B got " + x);
}
}


public class D : B
{
public readonly C dc = new C("D");


public D(): this("ha")
{
Console.WriteLine("D");
}
public D(string x) : base(x)
{
Console.WriteLine("D got " + x);
}
}


public class C
{
public C(string caller)
{
Console.WriteLine(caller + "'s C.");
}
}

结果:

D's C.
B's C.
A's C.
A
A got ha
B got ha
D got ha
D

巧合的是,这也是一个最常被问到的面试问题,并在 带演示的 youtube 视频中解释。

第一件事不要试图记住顺序。 在父子关系中逻辑地思考,孩子建立在父母关系的顶部。显然,首先应该创建 Parent 实例,然后创建 child。

所以首先父构造函数触发,然后子构造函数触发。

但是等一下,在初始化器方面,情况有所不同。

对于初始值设定项,首先运行子初始值设定项,然后运行父初始值设定项。

下面是相同的图示。因此,构造函数代码触发 Parent to Child,初始化器触发 Child to Parent。

C# constructor execution