C# 定数constとreadonlyの違いと使い分け

C#

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の比較表

特徴constreadonly
初期化コンパイル時実行時にコンストラクタ内、もしくはフィールド宣言時
型の制約プリミティブ型(値型)、string、enum全ての型で使用可能
static指定暗黙的に staticstatic にする場合は明示的にstatic宣言
ローカル変数使用可能使用不可
ただしクラスのメンバーフィールドには使える
外部アッセンブリからの参照値を変更したら再ビルドが必要値は動的に参照されるので再ビルドは不要

使い分けのガイドライン

  1. 変更されることが絶対にないリテラル値(数学の定数など)には const を使う。
  2. 実行時に計算する値や外部設定に依存する値は readonly を使う。
  3. 参照型インスタンスを定数的に扱いたい場合は必ず readonly
  4. バージョン間の互換性を重視するライブラリ開発では、再ビルド回避のため readonly を検討する。

コメント

タイトルとURLをコピーしました