フィールド (fields)

定数 (Constants)

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

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

    Foo()
    {
        r1 = 0;
    }

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

const

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

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

class Foo
{
    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: 'Foo.a1' に割り当てられた式は定数でなければなりません。
    const MyClass c1 = new MyClass(); // error CS0133: 'Foo.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

参考

参考書

MSDN (Microsoft Developer Network) から検索