9

2つのクラスがあるとしましょう:

public abstract class Foo
{
    static Foo()
    {
        print("4");
    }
}

public class Bar : Foo
{
    static Bar()
    {
        print("2");
    }

    static void DoSomething()
    {
        /*...*/
    }
}

呼び出した後Bar.DoSomething()(Bar クラスにアクセスするのはこれが初めてであると仮定します)、イベントの順序は次のようになると予想していました。

  1. Foo の静的コンストラクター (ここでも、最初のアクセスを想定) > print4
  2. バーの静的コンストラクター > 印刷2
  3. 実行DoSomething

42一番下の行で、印刷されることを期待しています。
テストしたところ、2印刷されているだけのようです。
そして、それは答えでさえありません

この振る舞いを説明できますか?

4

2 に答える 2

11

仕様には次のように記載されています。

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

  1. クラスのインスタンスが作成されます。
  2. クラスの静的メンバーのいずれかが参照されています。

基本クラスのメンバーを参照していないため、コンストラクターは実行されていません。

これを試して:

public abstract class Foo
{
    static Foo()
    {
        Console.Write("4");
    }

    protected internal static void Baz()
    {
        // I don't do anything but am called in inherited classes' 
        // constructors to call the Foo constructor
    }
}

public class Bar : Foo
{
    static Bar()
    {
        Foo.Baz();
        Console.Write("2");
    }

    public static void DoSomething()
    {
        /*...*/
    }
}

詳細については:

于 2013-11-20T09:52:23.377 に答える
6

基本クラスの静的コンストラクターが呼び出されない理由は、基本クラスの静的メンバーにまだアクセスしておらず、派生クラスのインスタンスを作成していないためです。

ドキュメントによると、これらは静的コンストラクターが呼び出される時間です。

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

以下のコードではDoSomething、基本クラスのコンストラクターを呼び出すときに呼び出されます

public abstract class Foo
{
    static Foo()
    {
        Console.Write("4");
        j = 5;
    }

    protected static int j;

    public static void DoNothing()
    {

    }
}

public class Bar : Foo
{
    static Bar()
    {
        Console.Write("2");
    }

    public static void DoSomething()
    {
        Console.Write(j);
    }
}
于 2013-11-20T09:46:55.320 に答える