6

、、の3つのクラスがBaseありDerivedますFinalDerivedから派生しBase、からFinal派生しDerivedます。3つのクラスすべてに静的コンストラクターがあります。Derivedと呼ばれるパブリック静的メソッドとしてのクラスSetup。を呼び出すとFinal.Setup、3つの静的コンストラクターがすべて実行されると思いますが、実行されるのは1つだけDerivedです。

サンプルソースコードは次のとおりです。

    abstract class Base
    {
        static Base()
        {
            System.Console.WriteLine ("Base");
        }
    }

    abstract class Derived : Base
    {
        static Derived()
        {
            System.Console.WriteLine ("Derived");
        }

        public static void Setup()
        {
            System.Console.WriteLine ("Setup");
        }
    }

    sealed class Final : Derived
    {
        static Final()
        {
            System.Console.WriteLine ("Final");
        }
    }

これは私には部分的にしか意味がありません。Final.Setup()呼び出しは実際にはのエイリアスにすぎないことを理解しているDerived.Setup()ので、で静的コンストラクターをスキップすることはFinal十分に公平に思えます。しかし、なぜ静的コンストラクターがBase呼び出されないのですか?

これを修正するには、のno-operation静的メソッドを呼び出すBaseか、のダミー静的メソッドにアクセスしBaseます。しかし、私は疑問に思っていました:この明らかに奇妙な行動の背後にある理由は何ですか?

4

3 に答える 3

5

静的コンストラクターは、次の場合に呼び出されます(TCPLによる)。

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

Main例として、実行が開始される静的メソッドを持つクラスについて考えてみます。静的コンストラクターがある場合は、Mainメソッドが呼び出される前に呼び出されます。

静的コンストラクターが実行される前であっても、静的フィールドはデフォルト値に初期化されてから、それらのフィールドに対して静的フィールド初期化子が実行されることに注意してください。その場合にのみ、静的コンストラクター(cctor)が実行されます。


質問に直接答えるには:静的コンストラクターは継承されず、直接呼び出すことはできません。したがって、抽象クラスに静的メソッドを指定して最初に呼び出すBase場合を除いて、シナリオでcctorは呼び出されません。あなたはすでに提案しました。BaseBase.Initialize()

理由については、C#(Javaではこれは異なります)を考えると単純です。静的メソッドは継承されないため、静的コンストラクターは継承されるべきではありません。これは、望ましくない副作用(そのクラスを参照するものがない場合に呼び出されるcctor)を引き起こす可能性があるためです。

于 2011-06-28T08:31:22.823 に答える
1

静的メソッドはクラスに属し、継承はありません。呼び出すことができるという事実Final.Setupは、Derived.Setupを呼び出すための単なる構文糖衣であるため、Finalの静的メンバーは参照されていません。したがって、静的コンストラクターは呼び出されません。Baseクラスについても同じです。静的メンバーには継承がないため、ここではBaseクラスは一切関与しません。

于 2011-06-28T08:30:31.093 に答える
0

C#のルールでは、クラスの最初のインスタンスが作成される前、または静的メンバーが変更される前に静的コンストラクターが呼び出されるように指示されています。

于 2011-06-28T08:27:09.010 に答える