150

在 C# 中,当你这样做时

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

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

4

8 回答 8

194

顺序是:

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

然后从最派生的类开始:

  • 为最衍生的类型执行变量初始化器
  • 构造函数链确定将调用哪个基类构造函数
  • 基类被初始化(递归所有这些:)
  • Foo() : this(...)执行此类中链中的构造函数主体(请注意,如果它们与etc链接,则可以有多个

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

如果您有兴趣,我有一个包含更多详细信息的页面。

于 2009-12-10T17:53:29.697 回答
61

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

于 2009-12-10T17:43:26.297 回答
17

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

于 2009-12-10T17:43:56.413 回答
17

不确定这是否应该是评论/答案,但对于那些通过示例学习的人来说,这个小提琴也说明了顺序: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
于 2016-08-16T20:05:06.237 回答
2

巧合的是,这也是一个被问到最多的面试问题,并在这个youtube 视频中进行了演示

首先不要试图记住顺序。在父子关系中逻辑思考,子建立在父子之上。所以显然应该创建第一个父实例,然后创建子实例。

因此,首先触发父构造函数,然后触发子构造函数。

但是,当涉及到初始化程序时,情况有所不同。

对于初始化程序,首先运行子初始化程序,然后运行父初始化程序。

下面是相同的图解表示。因此构造函数代码将 Parent 触发到 Child 并且 Initializers 从 Child 触发到 Parent。

C#构造函数执行

于 2021-06-20T15:48:02.450 回答
1

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

答案是它首先调用基地。

[以下旧问题的原始答案]

你是在问你什么时候做构造函数调用的“基础”位?

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

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

        }
    }

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

        }
    }

在此示例中,TerrainCollision源自CollisionBase. 通过以这种方式链接构造函数,它确保使用提供的参数在基类上调用指定的构造函数,而不是默认构造函数(如果基类上有一个)

于 2009-12-10T17:45:42.877 回答
0

你的问题有点不清楚,但我假设你的意思是问以下问题

何时调用 XNA 对象的基本构造函数与使用隐含的默认构造函数

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

  • 什么场景
  • 的基础对象的类型是TerrainCollision什么?

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

于 2009-12-10T17:44:19.900 回答
0

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

于 2015-07-20T12:04:11.970 回答