C#で時々迷う定数定義、const と static readonly の使い分けに関してまとめた。
#const
constフィールドは、コンパイル時定数の扱い。(MSDN)
- 変数のように扱える定数(暗黙的 static)
- 宣言時にのみ初期化可能(コンパイル時に値が埋め込まれる)
- readonly より実行速度が速い
- switch文やデフォルト引数に使える
- インスタンスを new した結果は割り当てられない(C#の組み込み型のみ)
- ※注意
- コンパイル時に決定されてしまうため、クラスライブラリなどでpublicなconst定数を定義しそれをアセンブリをまたいで参照してしまった場合、将来ライブラリ側の定数を変更しても参照されたアセンブリ側をコンパイルしなおさない限り更新されないという問題がある(constのバージョニング問題)
#readonly
readonlyフィールドは、実行時定数の扱い。(MSDN)
- 実際は、読み取り専用の代入不可な変数
- 宣言時の他に、コンストラクタ内でも初期化可能
- 定数であるconstよりは、僅かに実行速度が遅い
- switch文やデフォルト引数には使えない
- インスタンスを new した結果を割り当てられる
#static readonly
- constが使いたいけど、使えない場合に、static readonly を使用する。
定数値のシンボル名が必要で、その値の型を const 宣言で使用できない場合、またはその値をコンパイル時に計算できない場合は、static readonly フィールドが役に立ちます。(MSDN – 定数用の static readonly フィールド)
#まとめ
基本的に、static readonly を使用する。
constは、属性に指定するパラメータや列挙型の定義など、コンパイル時に値が必要な場合にのみ使用する。
Effective C# でも、const よりも readonly の使用が推奨されている。
高いパフォーマンスが求められていて、なおかつ将来にわたって変更されることがないことが明らかな場合にのみコンパイル時定数を使用するべきです。