C#のconst(定数)とreadonlyは、どちらも定数的に扱われますが、実は結構な違いがあります。ここではその違いと使い分けを整理してみます。
const(定数)
- コンパイル時に値が決定する文字通りの定数です。コンパイル時に決定された値は、プログラムの実行中には変更できません。
- フィールド宣言時に必ず初期化する必要があります。
- constは暗黙的にstaticになるので、インスタンス単位でアクセスすることはできません。
- 型はプリミティブ型(数値型、ブール型)、文字列、enumに限定されます。つまり値型のみです。
- メソッド内でローカル変数として宣言して使用することができます。
C#
public class
{
public const int MaxUsers = 1000;
public const string CompanyName = "Stack Cat.";
public const double PI = 3.14159;
public void ExMethod()
{
const int LocalConstant = 100; // ローカルなconst
Console.WriteLine($"Max Users: {MaxUsers}");
Console.WriteLine($"Local Constant: {LocalConstant}");
}
}
readonly
- 実行時に初期化されます。
- フィールド宣言時もしくは、static readonly の場合はstatic コンストラクタ、インスタンス readonly の場合はインスタンスコンストラクタ内でのみ代入可能です。
- プリミティブ型だけでなく、参照型や構造体も利用可能です。
- インスタンスごとの定数、あるいはクラス単位の定数(static)ともに対応しています。
C#
public class Configuration
{
// インスタンスが生成された時刻を保持
public readonly DateTime CreatedAt = DateTime.Now;
// クラス単位で一度だけ初期化
public static readonly Regex HtmlTag = new Regex("<.*?>", RegexOptions.Compiled);
public Configuration()
{
// 追加の初期化も可能
CreatedAt = DateTime.UtcNow;
}
}
const対readonlyの比較表
特徴 | const | readonly |
---|---|---|
初期化 | コンパイル時 | 実行時にコンストラクタ内、もしくはフィールド宣言時 |
型の制約 | プリミティブ型(値型)、string、enum | 全ての型で使用可能 |
static指定 | 暗黙的に static | static にする場合は明示的にstatic宣言 |
ローカル変数 | 使用可能 | 使用不可 ただしクラスのメンバーフィールドには使える |
外部アッセンブリからの参照 | 値を変更したら再ビルドが必要 | 値は動的に参照されるので再ビルドは不要 |
使い分けのガイドライン
- 変更されることが絶対にないリテラル値(数学の定数など)には
const
を使う。 - 実行時に計算する値や外部設定に依存する値は
readonly
を使う。 - 参照型インスタンスを定数的に扱いたい場合は必ず
readonly
。 - バージョン間の互換性を重視するライブラリ開発では、再ビルド回避のため
readonly
を検討する。
コメント