Порядок выполнения конструктора C#

В C#, когда вы делаете

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

сначала выполняется конструктор класса, а затем вызывается конструктор суперкласса или сначала вызывается базовый конструктор?

7 ответов


заказ:

  • переменные-члены инициализируются значениями по умолчанию для всех классов в иерархии

затем, начиная с самого производного класса:

  • инициализаторы переменных выполняются для наиболее производного типа
  • конструктор цепочки работает, какой конструктор базового класса будет называться
  • базовый класс инициализируется (рекурсивно все это :)
  • тела конструктора цепочка в этом классе выполняется (обратите внимание, что может быть несколько, если они связаны с Foo() : this(...) etc

обратите внимание, что в Java, базовый класс инициализируется до запускаются инициализаторы переменных. Если вы когда-либо переносите какой-либо код, это важное различие, о котором нужно знать:)

У меня есть страницы если вам интересно.


сначала он вызовет базовый конструктор. Также имейте в виду, что если вы не поставите :base(param1) после вашего конструктора будет вызван пустой конструктор базы.


конструктор класса baseclass называется первой.


не уверен, что это должен быть комментарий / ответ, но для тех, кто учится на примере, эта скрипка также иллюстрирует порядок: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

[Edit: за то время, пока я отвечал, вопрос полностью изменился].

ответ заключается в том, что он называет первой базы.

[оригинальный ответ на старый вопрос ниже]

вы спрашиваете, когда вы будете делать" базовый " бит вызова конструктора?

Если это так, вы бы "цепочка" вызов базового конструктора, если класс является производным от другого класса, который имеет этот конструктор:

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

        }
    }

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

        }
    }

В этом примере TerrainCollision происходит от CollisionBase. Связывая таким образом конструкторы, он гарантирует, что указанный конструктор вызывается в базовом классе с предоставленными параметрами, а не конструктором по умолчанию (если он есть на базе)


ваш вопрос немного неясен, но я предполагаю, что вы хотели спросить следующее

когда я вызываю базовый конструктор для моего объекта XNA против использования impilict конструктор по умолчанию

ответ на этот вопрос сильно зависит от вашего сценария и базовый объект. Не могли бы Вы уточнить немного остроумие следующее

  • каков сценарий
  • тип объекта база TerrainCollision?

мой лучший ответ заключается в том, что в случае, когда у вас есть параметры, которые совпадают с параметрами конструктора базового класса, вы почти наверняка должны его вызывать.


механизм конструктора намного лучше, поскольку он оставляет приложение для использования цепочки конструкторов, и если вы должны были расширить приложение, оно позволяет через наследование возможность вносить минимальные изменения кода. Джон Скитс Статьи