C# 构造函数执行顺序

发布于 2024-08-14 17:30:06 字数 132 浏览 5 评论 0原文

在C#中,执行时

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

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

In C#, when you do

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

弄潮 2024-08-21 17:30:06

顺序是:

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

然后从最派生的类开始:

  • 对最派生的类型执行变量初始值设定
  • 项 构造函数链确定将调用哪个基类构造
  • 函数类被初始化(递归所有这些:)
  • 执行此类中链中的构造函数体(请注意,如果它们与 Foo() 链接,则可以有多个构造函数体: this(...)< /code> 等

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

我有一个 包含更多详细信息的页面

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

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

I have a page with more details if you're interested.

べ映画 2024-08-21 17:30:06

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

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.

萌梦深 2024-08-21 17:30:06

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

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

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
仅冇旳回忆 2024-08-21 17:30:06

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

The constructor of the baseclass is called first.

忆离笙 2024-08-21 17:30:06

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

答案是它首先调用基地。

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

您是否在问何时执行构造函数调用的“基本”位?

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

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

        }
    }

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

        }
    }

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

[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, TerrainCollision derives 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)

偏闹i 2024-08-21 17:30:06

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

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

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

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

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

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

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?

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.

脱离于你 2024-08-21 17:30:06

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文