インスタンスコンストラクターの後に静的コンストラクターが呼び出されますか? 質問する

インスタンスコンストラクターの後に静的コンストラクターが呼び出されますか? 質問する

皆さん、このような質問はすでに質問済みしかし、回答の中には私が見ている問題の説明はありませんでした。

問題は、C# プログラミング ガイド言う:

静的コンストラクターは、静的データを初期化するため、または一度だけ実行する必要がある特定のアクションを実行するために使用されます。最初のインスタンスが作成されるか、静的メンバーが参照される前に、自動的に呼び出されます。

特に、静的コンストラクターは、クラスのインスタンスが作成される前に呼び出されます。(これによって、インスタンスの作成前に静的コンストラクターが終了することが保証されるわけではありませんが、これは別の話です。)

次のサンプルコードを考えてみましょう:

using System;

public class Test
{
    static public Test test = new Test();
    static Test()
    {
        Console.WriteLine("static Test()");
    }
    public Test()
    {
        Console.WriteLine("new Test()");
    }
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Main() started");
        Console.WriteLine("Test.test = " + Test.test);
        Console.WriteLine("Main() finished");
    }
}

出力は次のようになります:

Main() が開始されました。
新しい Test()
静的 Test()
Test.test = Test
Main() が完了しました。

インスタンスコンストラクタが終了し、インスタンスが作成されたことがわかります。前に静的コンストラクタ始まるこれはガイドと矛盾していませんか? 静的フィールドの初期化は、静的コンストラクターの暗黙的な部分であると考えられるのでしょうか?

ベストアンサー1

staticフィールドのインライン初期化子は、明示的なstaticコンストラクターの前に実行されます。

コンパイラはクラスを次のように変換します。

public class Test {
    .cctor {    //Class constructor
        Test.test = new Test();                //Inline field initializer
        Console.WriteLine("static Test()");    //Explicit static ctor
    }
    .ctor { ... }    //Instance constructor
}

これは宣言順序とは無関係であることに注意してください。

引用するとスペック:

クラスの静的フィールド変数初期化子は、クラス宣言に現れるテキストの順序で実行される一連の割り当てに対応します。静的コンストラクタの場合(第10.11節)クラス内に存在する場合、静的フィールド初期化子の実行は、その静的コンストラクターの実行の直前に行われます。

おすすめ記事