問題となるソースコード
using System;
class SampleCode
{
static readonly int Y = X;
static readonly int X = 10;
[STAThread]
static void Main(string[] args)
{
Console.WriteLine(Y);
}
}
このコードをcsc.exeでコンパイルして実行するとどうなるでしょう?
(a). Xが未定義としてコンパイルエラーになる
(b). 10が出力される
(c). (a)でも(b)でもない
実行結果
0
タイトル通りの挙動になっています。
ちなみにreadonlyかどうかは影響はないです。(ユースシーン的にreadonly1を使うときにうっかりしそうなので書いた次第。)
言語仕様
静的フィールドを初期化するための静的コンストラクターを指定しないと、すべての静的フィールドは、「C# 型の既定値」で示されている既定値に初期化されます。
静的コンストラクターは自動的に呼び出されます。 これにより、最初のインスタンスが作成される前、またはそのクラス (基底クラスではない) で宣言された静的メンバーが参照される前に、クラスが初期化されます。 静的コンストラクターは、インスタンス コンストラクターの前に実行されます。 (中略)。 静的フィールド変数初期化子が静的コンストラクターのクラスに存在する場合、それらは、クラス宣言に出現するテキストの順序で実行されます。 初期化子は、静的コンストラクターの実行直前に実行されます。
ildasmによる逆アセンブル結果
参考まで。
名称からして「静的コンストラクター」だと思われますが、言語仕様の章で抜粋した記載中の用語「静的フィールド変数初期化子」を内包しているっぽい。
.method private hidebysig specialname rtspecialname static
void .cctor() cil managed
{
// コード サイズ 18 (0x12)
.maxstack 8
IL_0000: ldsfld int32 SampleCode::X
IL_0005: stsfld int32 SampleCode::Y
IL_000a: ldc.i4.s 10
IL_000c: stsfld int32 SampleCode::X
IL_0011: ret
} // end of method SampleCode::.cctor
実行環境
コンパイル環境:
Microsoft (R) Visual C# Compiler version 4.8.4084.0
for C# 5
-
static readonlyの代わりにconstを推奨するものではありません。 ↩