C#构造函数执行顺序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1882692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:37:46  来源:igfitidea点击:

C# constructor execution order

c#inheritanceconstructorconstructor-chaining

提问by webdreamer

In C#, when you do

在 C# 中,当你这样做时

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

is the constructor of the class executed first, and then the superclass constructor is called or does it call the base constructor first?

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

采纳答案by Jon Skeet

The order is:

顺序是:

  • Member variables are initialized to default values for all classes in the hierarchy
  • 成员变量被初始化为层次结构中所有类的默认值

Then starting with the most derived class:

然后从最派生的类开始:

  • Variable initializers are executed for the most-derived type
  • Constructor chaining works out which base class constructor is going to be called
  • The base class is initialized (recurse all of this :)
  • The constructor bodies in the chain in this class are executed (note that there can be more than one if they're chained with Foo() : this(...)etc
  • 为派生最多的类型执行变量初始值设定项
  • 构造函数链确定将调用哪个基类构造函数
  • 基类被初始化(递归所有这些:)
  • 此类中链中的构造函数体被执行(注意,如果它们与Foo() : this(...)etc链在一起,则可以有多个)

Note that in Java, the base class is initialized beforevariable initializers are run. If you ever port any code, this is an important difference to know about :)

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

I have a page with more detailsif you're interested.

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

回答by Yuriy Faktorovich

It will call the base constructor first. Also keep in mind that if you don't put the :base(param1)after your constructor, the base's empty constructor will be called.

它将首先调用基础构造函数。还请记住,如果您不将 放在:base(param1)构造函数之后,则会调用基类的空构造函数。

回答by tanascius

The constructor of the baseclass is called first.

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

回答by JaredPar

Your question is a bit unclear but I'm assuming you meant to ask the following

你的问题有点不清楚,但我假设你打算问以下问题

When to I call the base constructor for my XNA object vs. using the impilict default constructor

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

The answer to this is highly dependent on both your scenario and the underlying object. Could you clarify a bit wit the following

对此的答案高度依赖于您的场景和底层对象。你能否澄清一下以下内容

  • What is the scenario
  • What is the type of the base object of TerrainCollision?
  • 什么场景
  • 的基础对象的类型是什么TerrainCollision

My best answer though is that in the case where you have parameters that line up with the parameters of the base class`s constructor, you should almost certainly be calling it.

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

回答by Rob Levine

[Edit: in the time it took me to answer, the question had totally changed].

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

The answer is that it calls the base first.

答案是它首先调用基数。

[Original answer to the old question below]

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

Are you asking when you would do the "base" bit of the constructor call?

您是在问什么时候会执行构造函数调用的“基本”位?

If so, you would "chain" a call to the constructor base if the class is derived from another class which has this constructor:

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

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

        }
    }

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

        }
    }

In this example, TerrainCollisionderives from CollisionBase. By chaining the constructors in this way, it ensures the specified constructor is called on the base class with the supplied parameters, rather than the default constructor (if there is one on the base)

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

回答by lloydom

Constructor mechanism is much better as it leaves the application to use constructor chaining and if you were to extend the application it enables through inheritance the ability to make minimal code changes. Jon Skeets Article

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

回答by user420667

Not sure if this should be a comment/answer but for those who learn by example this fiddle illustrates the order as well: https://dotnetfiddle.net/kETPKP

不确定这是否应该是评论/答案,但对于那些通过示例学习的人来说,这个小提琴也说明了顺序: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.");
    }
}

Result:

结果:

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