フィールド (fields)

定数 (Constants)

修飾子 評価タイミング 宣言での初期化 コンストラクタでの初期化
const コンパイル時 ○ (必須) ×
readonly 実行時
class MyClass
{
    const int c1 = 0;
    const int c2;    // error CS0145: const フィールドに値を指定する必要があります。

    readonly int r1;
    readonly int r2; // warning CS0649: フィールド 'MyClass.r2' は割り当てられません。常に既定値 0 を使用します。

    MyClass()
    {
        r1 = 0;
    }

    void A()
    {
        c1 = 1; // error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
        r1 = 1; // error CS0191: 読み取り専用フィールドに割り当てることはできません (コンストラクター、変数初期化子では可 )。
    }
}

const

constはコンパイル時に評価されるため、宣言での初期化が必須です。そしてconstで定数に指定できるのは、

に限られます。const (C# リファレンス) | MSDN

class MyClass
{
    const int i = 1;
    const bool b = true;
    const MyEnum e = MyEnum.A;
    const string s = "abc";

    const int[] a = null;   // null参照
    const MyClass c = null; // null参照

    const int[] a1 = new int[3];      // error CS0133: 'MyClass.a1' に割り当てられた式は定数でなければなりません。
    const MyClass c1 = new MyClass(); // error CS0133: 'MyClass.c1' に割り当てられた式は定数でなければなりません。

    void A()
    {
        i = 10;       // error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
        b = false;    // error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
        e = MyEnum.B; // error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
        s = "x";      // error CS0131: 代入式の左辺には変数、プロパティ、またはインデクサーを指定してください。
    }
}

readonly

readonlyは実行時に評価されるため、

readonly uint l = (uint)DateTime.Now.Ticks;

のような毎回異なる値も定数にできます。また初期化は宣言またはコンストラクタのいずれでもよく、初期化しない場合には既定値が設定されます。readonly (C# リファレンス) | MSDN

静的フィールド

静的なフィールドは、初めてアクセスされる前、もしくは静的コンストラクタがあるならばそれが呼び出される前に初期化されます。静的メンバー - 静的クラスと静的クラス メンバー - C# プログラミング ガイド | Microsoft Learn

値をコンパイル時に決定できるならば、static readonlyではなくconstとします。 CA1802: Use Literals Where Appropriate - Visual Studio 2015 | Microsoft Learn c# - 'Static readonly' vs. 'const' - Stack Overflow

宣言時に値が確定しているならばそこで初期化して、静的コンストラクタでは初期化しないようにします。CA1810: Initialize reference type static fields inline - Visual Studio 2015 | Microsoft Learn

class MyClass
{
    static int a = 1; // ここで初期化する
    static int b;

    // 静的コンストラクタ
    static MyClass()
    {
        b = 1; // ここでも初期化できる
    }
}

非パブリックなフィールドへのアクセス

Type.GetField()で任意のフィールドの情報を取得し、アクセスできます。

参考

参考書

Microsoft Learnから検索