6

次のコード例を検討してください。

public class A<T> 
{
    public static T TheT { get; set; }
}
public class B : A<string>
{
    static B() {
        TheT = "Test";
    }
}

public class Program {
    public static void Main(String[] args) {
        Console.WriteLine(B.TheT);
    }
}

ここB.TheTはヌルです。ただし、次のMainようにメソッドを変更します。

public static void Main() {
    new B();
    Console.WriteLine(B.TheT);
}

B.TheT予想どおり、「テスト」です。これにより静的コンストラクターが強制的に実行されることは理解できますが、最初のケースでこれが発生しないのはなぜですか?

仕様を読んでみましたが、これが私の注意を引きました (§10.12):

[...] 静的コンストラクターの実行は、アプリケーション ドメイン内で発生する次のイベントの最初のイベントによってトリガーされます。

• [...]

• クラス型の静的メンバーのいずれかが参照されている。

これについての私の解釈は、 はTheTのメンバーではないためB、 の静的コンストラクターBは強制的に実行されないということです。これは正しいです?

それが正しい場合、どのBように初期化する方法を指定するのが最善でしょうTheTか?

4

3 に答える 3

5

A.予想通り、TheTは「テスト」です。これにより静的コンストラクターが強制的に実行されることは理解できますが、最初のケースでこれが発生しないのはなぜですか?

基本的に、あなたは実際には参照していませB。ILを見ると、コードが実際には次のものと同等であることがわかると思います。

public static void Main(String[] args) {
    Console.WriteLine(A<string>.TheT);
}

コンパイラは、あなたが書いたとしても、それが本当にB.TheTあなたが意図したメンバーであることを理解しました。

それが正しければ、AにTheTの初期化方法を指定させるにはどうすればよいでしょうか。

正直に言うと、最初はこれを避けようとしますが、静的メソッドをいつでも追加できますB

public static void Initialize() {
    // Type initializer will be executed now.
}
于 2012-10-18T11:45:17.160 に答える
0

静的コンストラクターは、最初のアクセスの前、または遅くとも最初のアクセスが行われたときに呼び出されます。つまり、最初のアクセスが行われたときに呼び出されたことはわかっていますが、どのくらい前に呼び出されたかはわかりません。ただし、アクセスがない場合は呼び出されません。したがって、呼び出された場合にのみ制御することはできません。

MSDNリファレンスによると

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

于 2012-10-18T11:47:57.377 に答える
0

2番目のケースでは静的コンストラクターと呼ばれ、派生したものではなく、実際の型の静的コンストラクターを呼び出します。したがって、あなたの場合、 ではなくの静的 ctorA<T> =>A<string>を呼び出します。A

この動作を証明するには、次のようにします。

public class Base {

    static Base() {
      "Base static".Dump(); 
    }
}

public class Derived : Base {

    static Derived() {
      "Derived static".Dump(); 
    }

    public static string temp = "Hello";
}

そして電話する

Derived.temp.Dump();

あなたは得るでしょう:

Derived static
Hello

これは、コードで実際に行うことです。派生A<string>にアクセスすると、デフォルトの静的 ctor が呼び出されます。

于 2012-10-18T11:49:02.627 に答える