静的コンストラクタ
静的メンバの初期化処理
静的フィールドは、インスタンスフィールドと同じように初期化できます。
private static int x = 10;
上記の静的フィールドは共通言語ランタイムに読み込まれた時点で初期化されます。しかし、初期化子に記述できるのは式であり、複数の文からなる初期化手続きには利用できません。
インスタンスメンバの初期化にはコンストラクタが用いられましたが、静的メンバの初期化には静的コンストラクタ(static constructor)が用いられます。静的コンストラクタはクラスが共通言語ランタイムに読み込まれた時点で、共通言語ランタイムから自動的に呼び出されます。他のメンバと同じように、以下のような静的コンストラクタ宣言(static constructor declaration)をクラス内に記述します。
static コンストラクタ名() { コンストラクタ本体 }
静的コンストラクタの宣言には、必ず static 修飾子を指定しなければなりません。コンストラクタ名は、インスタンスコンストラクタと同様にクラス名に一致させます。
静的コンストラクタは、インスタンスコンストラクタのようにコードから明示的に呼ばれるものではないため public などのアクセス修飾子を指定することはできません。 同様の理由から静的コンストラクタはパラメータを受け取らず、戻り値もありません。
静的コンストラクタは Main() メソッドが実行されるよりも前に実行される点に注意してください。
class Incubator { public string Name { get; set; } } class MagicalGirl { public static Incubator Incubator { get; private set; } static MagicalGirl() { Incubator = new Incubator(); Incubator.Name = "キュゥべえ"; } } class Test { public static void Main(string[] args) { System.Console.WriteLine( MagicalGirl.Incubator.Name + "「僕と契約して魔法少女になってよ!」"); } }
コード1は MagicalGirl クラスの Incubator 静的プロパティの初期化に静的コンストラクタを用いています。Main() メソッドが実行される時点で、すでに静的コンストラクタが実行され有効なインスタンスが Incubator プロパティに設定されていることが確認できます。
静的フィールドの初期化と静的コンストラクタ
インスタンスフィールドの初期化子がインスタンスコンストラクタの実行よりも優先されるのと同じように、静的フィールドの初期化は静的コンストラクタよりも優先されます。静的コンストラクタが実行される時点で、静的フィールドの初期化は終了しています。
class MagicalGirl { public static string title = "魔法の呪文はリリカルなの?"; static MagicalGirl() { System.Console.WriteLine(title); } } class Test { public static void Main(string[] args) { MagicalGirl obj = new MagicalGirl(); } }
コード2の MagicalGirl クラスは title 静的フィールドを初期化子で初期化しています。静的コンストラクタで title フィールドを出力していますが、正しく初期化されていることが確認できます。Main() メソッドでインスタンスを生成しているのは、MagicalGirl クラスを共通言語ランタイムに読み込ませるためであり意味はありません。