11

次のプログラムからの出力は次のとおりです。

Non-Static
Static
Non-Static

これはコンパイラのバグですか?私は期待しました:

Static
Non-Static
Non-Static

静的コンストラクターは常に非静的コンストラクターの前に呼び出されると思ったからです。

.net3.5と.net4.0の両方を使用してVisualStudio2010でこれをテストしました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StaticConstructorBug
{
    class Program
    {
        static void Main(string[] args)
        {
            var mc = new MyClass();

            Console.ReadKey();
        }
    }

    public class MyClass
    {
        public MyClass()
        {
            Console.WriteLine("Non-static");
        }

        static MyClass()
        {
            Console.WriteLine("Static");
        }

        public static MyClass aVar = new MyClass();
    }
}
4

4 に答える 4

11

ECMA334§17.4.5.1を参照してください。

17.4.5.1静的フィールドの初期化

クラス宣言の静的フィールド変数初期化子は、クラス宣言に表示されるテキストの順序で実行される一連の割り当てに対応します。静的コンストラクター(§17.11)がクラスに存在する場合、静的フィールド初期化子の実行は、その静的コンストラクターを実行する直前に行われます。それ以外の場合、静的フィールド初期化子は、そのクラスの静的フィールドを最初に使用する前に、実装に依存する時間に実行されます。

具体的には、「静的フィールド初期化子の実行は、その静的コンストラクターを実行する直前に行われます」。

静的static MyClass aVarコンストラクターを実行する前に初期化する必要があります(または、少なくとも、そのように表示する必要があります)。その静的メンバーがない場合は、静的コンストラクターを非静的コンストラクターの前に呼び出す必要があります。

それでもMyClassシングルトンが必要な場合は、それをコンテナクラスに入れて、それを使用して参照できます。例:

public static class MyClassSingleton
{
    public static MyClass aVar = new MyClass();
}
于 2010-05-27T23:10:02.460 に答える
5

行が原因public static MyClass aVar = new MyClass();です。

実際、これaVar = new MyClass();は静的コンストラクターの前に付加されます。したがって、静的コンストラクターは次のようになります。

static MyClass() {
    Console.WriteLine("Static");
}

に変更されます:

static MyClass() {
    aVar = new MyClass(); // this will run instance contstructor and prints "Non-Static"
    Console.WriteLine("Static");
}
于 2010-05-27T23:12:29.277 に答える
1

これpublic static MyClass aVar = new MyClass();は静的コンストラクターの一部です。リフレクターで見ると、次のようになります。

static MyClass()
{
    aVar = new Program.MyClass();
    Console.WriteLine("Static");
}

したがって、結果は今や明らかなはずです。

于 2010-05-27T23:03:27.127 に答える
0

MSDNリンクから:

静的コンストラクターは、最初のインスタンスが作成される前、または静的メンバーが参照される前に、クラスを初期化するために自動的に呼び出されます。

これは、最後の行のインスタンスの静的インスタンス化が原因だと思いますが、MSDNによると、静的コンストラクターは最初のインスタンスが呼び出される前に発生する必要があります。

于 2010-05-27T23:04:01.070 に答える