静的コンストラクターはいつC#で呼び出されますか?


88

静的コンストラクターを含むクラスがある場合、そのクラスを含むアセンブリが最初にロードされたとき、またはそのクラスへの最初の参照がヒットしたときに、そのコンストラクターが呼び出されますか?

回答:


93

クラスに初めてアクセスしたとき。

静的コンストラクター(C#プログラミングガイド)

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


6
「最初のインスタンスが作成される前、または静的メンバーが参照される前」と書かれているのは興味深いことです。それが実際に呼び出されるとき、そこにはいくらかの余裕があります。
Tim Barrass

6
-他の回答で参照ジョンスキートの記事を参照-により仕様の他のいくつかの要件に@TimBarrassは「直前」は、実際にある「前」ことが判明stackoverflow.com/a/1437372/477420を
アレクセイLevenkov

A static constructor is used to initialize any static data番号。static initializer静的なものを初期化するために使用する方が良いです。
YoushaAleayoub19年

41

簡単なドキュメントにもかかわらず、期待するほど単純ではありません。Jon Skeetの記事http://csharpindepth.com/Articles/General/Beforefieldinit.aspxで、この質問について詳しく説明します。

概要:

静的コンストラクターはすぐに実行されることが保証されています、そのクラスのメンバーへの最初の参照のに-インスタンスの作成またはクラスの独自の静的メソッド/プロパティ。

静的イニシライザー(静的コンストラクターがない場合)は、特定のフィールドを最初に参照する前であればいつでも実行されることが保証されていることに注意してください。


言及された記事は現在、ジョンスキートのサイトにあります:csharpindepth.com/Articles/General/Beforefieldinit.aspx
Sudhanshu Mishra

次の質問stackoverflow.com/questions/32525628/…「即時」の動作が非常に明白な場合を示します。
Alexei Levenkov 2015

1
実際、コンソールアプリケーションのMainメソッドが実行を開始する直前に静的コンストラクターが呼び出された場合がありました。
HerpDerpington 2018年

19

静的コンストラクターは、クラスで何かを使用する前に呼び出されますが、それがいつ発生するかは実装次第です。

最初の静的メンバーにアクセスする前、および最初のインスタンスが作成される前に呼び出されることが保証されています。クラスが使用されない場合、静的コンストラクターが呼び出される保証はまったくありません。


2
その実装がECMAC#仕様に従っている場合、それが発生するの「実装まで」ではありません。「静的コンストラクターの実行は、アプリケーションドメイン内で発生する次のイベントの最初のイベントによってトリガーされます。[1]のインスタンスクラスが作成されます。[2]クラスの静的メンバーのいずれかが参照されます。」(セクション17.11、ecma-international.org / publications / standards / Ecma
LukeH 2009

1
@Luke:「静的コンストラクターの実行の正確なタイミングは実装に依存します」ondotnet.com/pub/a/dotnet/2003/07/07/staticxtor.html
Guffa

2
@Guffa:それは記事の著者の解釈かもしれませんが、C#仕様のMicrosoftまたはECMA / ISOバージョンではその表現は見つかりません。
LukeH 2009

1

静的メソッドが親クラスから呼び出される場合、明示的に指定されていても、静的コンストラクターは呼び出されません。これは、b.methoda()が呼び出された場合にbコンストラクターが呼び出されない例です。

static void Main(string[] args)
{
    b.methoda();
}

class a
{
    public static void methoda()
    {
        //using initialized method data
    }
}

class b : a
{
    static b()
    {
        //some initialization
    }
}    

1

静的コンストラクターには他の場所で答えられる落とし穴があるようですが、簡単な説明に消化するのに時間がかかりました。すべてのドキュメントと説明では、静的コンストラクター/イニシャライザーは、最初のクラスがインスタンス化される前、または最初の静的フィールドが参照される前に実行されることが「保証」されていると主張しています。それ自体のインスタンス(ニワトリ/卵)を作成するクラスに静的シングルトンを配置しようとすると、落とし穴が発生します。この場合、静的コンストラクターはインスタンスコンストラクターの後に呼び出されることになります。私の場合、インスタンスコンストラクターには静的データに依存するコードが含まれていました。

インスタンスコンストラクターの後に呼び出される静的コンストラクター?

静的コンストラクターは、非静的コンストラクターの後に実行できます。これはコンパイラのバグですか?

(私にとっての答えは、シングルトンを別のクラスに配置するか、必要になる前にインスタンスコンストラクターで静的データを手動で初期化することでした)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.