web-dev-qa-db-ja.com

C#コンストラクターの実行順序

C#では、行うとき

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

クラスのコンストラクターが最初に実行され、次にスーパークラスコンストラクターが呼び出されるか、最初に基本コンストラクターを呼び出しますか?

112
webdreamer

順序は次のとおりです。

  • メンバー変数は、階層内のすべてのクラスのデフォルト値に初期化されます

次に、最も派生したクラスから始めます。

  • 変数の初期化子は、最も派生した型に対して実行されます
  • コンストラクターチェーンは、どの基本クラスコンストラクターを呼び出すかを決定します
  • 基本クラスが初期化されます(これをすべて再帰します:)
  • このクラスのチェーン内のコンストラクター本体が実行されます(Foo() : this(...)などでチェーン化されている場合、複数存在する可能性があることに注意してください。

Javaでは、基本クラスが初期化されることに注意してくださいbefore変数初期化子が実行されます。コードを移植する場合、これは知っておくべき重要な違いです:)

興味がある場合は 詳細が記載されたページ があります。

161
Jon Skeet

最初に基本コンストラクターを呼び出します。また、コンストラクタの後に:base(param1)を付けないと、ベースの空のコンストラクタが呼び出されることに注意してください。

48

ベースクラスのコンストラクターが最初に呼び出されます。

12
tanascius

これがコメント/回答であるかどうかはわかりませんが、例で学ぶ人のために、このフィドルは順序も示しています: 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
7
user420667

[編集:答えるまでにかかった時間で、質問は完全に変わりました]。

答えは、最初にベースを呼び出すことです。

[以下の古い質問に対する元の回答]

コンストラクター呼び出しの「ベース」ビットをいつ実行するかを尋ねていますか?

その場合、クラスがこのコンストラクタを持つ別のクラスから派生している場合、コンストラクタベースへの呼び出しを「チェーン」します。

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

        }
    }

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

        }
    }

この例では、TerrainCollisionCollisionBaseから派生しています。このようにコンストラクターをチェーンすることにより、指定されたコンストラクターがデフォルトのコンストラクターではなく、指定されたパラメーターで基本クラスで呼び出されるようにします(ベースにコンストラクターがある場合)

1
Rob Levine

あなたの質問は少し不明瞭ですが、私はあなたが次の質問をするつもりだったと思います

XNAオブジェクトのベースコンストラクターを呼び出す場合と、暗黙のデフォルトコンストラクターを使用する場合

これに対する答えは、シナリオと基礎となるオブジェクトの両方に大きく依存します。次のことを少しはっきりさせてください

  • シナリオは何ですか
  • TerrainCollisionのベースオブジェクトのタイプは何ですか?

私の最良の答えは、基本クラスのコンストラクターのパラメーターと並ぶパラメーターがある場合、ほぼ確実に呼び出す必要があるということです。

0
JaredPar

コンストラクターメカニズムは、アプリケーションがコンストラクターチェーンを使用できるようにし、アプリケーションを拡張する場合、継承を通じて最小限のコード変更を行う機能を有効にします。 ジョン・スキーツの記事

0
lloydom