C# constとは?readonlyとの違い・使い方・エラー対策を初心者向けに徹底解説

はじめに

C#でプログラムを書いていると、constというキーワードを見かけることがあります。

たとえば、次のようなコードです。

C#
const double Pi = 3.14;
const string AppName = "SampleApp";

constは、簡単に言うと「後から変更できない値」を定義するためのキーワードです。プログラム内で何度も使う固定値に名前を付けておくことで、コードの読みやすさや保守性を高められます。

一方で、C#にはreadonlystatic readonlyといった似た仕組みもあります。そのため、初心者のうちは「constreadonlyは何が違うの?」「どちらを使えばいいの?」「なぜDateTimeはconstにできないの?」と迷いやすいポイントが多いです。

この記事では、C#のconstについて、基本的な使い方からreadonlyとの違い、よくあるエラー、実践的な使いどころまで初心者向けにわかりやすく解説します。

1. C# constとは?初心者向けにわかりやすく解説

1-1. constは「変更できない定数」を宣言するキーワード

C#のconstは、変更できない値、つまり「定数」を宣言するためのキーワードです。

通常の変数は、あとから別の値を代入できます。

C#
int price = 100;
price = 200;

このコードでは、priceの値を100から200へ変更できます。

一方、constで宣言した値は変更できません。

C#
const int MaxCount = 10;
MaxCount = 20; // エラー

constで宣言したMaxCountには、あとから別の値を代入できません。

つまり、constは「プログラム中で変わらない値」に名前を付けるために使います。

1-2. constで宣言した値はコンパイル時に決まる

constの大きな特徴は、値がコンパイル時に決まることです。

コンパイル時とは、C#のソースコードが実行可能な形に変換されるタイミングのことです。constの値は、この時点で確定している必要があります。

たとえば、次のコードは問題ありません。

C#
const int TaxRate = 10;
const string Message = "Hello";

10"Hello"は、コードを見た時点で値が決まっています。

しかし、次のようなコードはエラーになります。

C#
const DateTime Today = DateTime.Now; // エラー

DateTime.Nowは、プログラムを実行した瞬間の日時によって値が変わります。コンパイル時には値が決まらないため、constにはできません。

1-3. 変数・readonly・staticとの違いをざっくり比較

constを理解するうえで、通常の変数、readonlystaticとの違いをざっくり押さえておきましょう。

通常の変数は、後から値を変更できます。

C#
int count = 1;
count = 2;

constは、宣言時に値を決める必要があり、後から変更できません。

C#
const int MaxCount = 10;

readonlyは、宣言時またはコンストラクタで値を設定でき、その後は変更できません。

C#
readonly int maxCount;

public Sample()
{
maxCount = 10;
}

staticは、インスタンスごとではなく、クラスに属するメンバーを表します。

C#
static int Count = 0;

そして、constは暗黙的にstaticのように扱われます。つまり、インスタンスを作らなくてもクラス名から参照できます。

C#
class Settings
{
public const int MaxCount = 10;
}

Console.WriteLine(Settings.MaxCount);

1-4. constを使うメリットと注意点

constを使う主なメリットは、コードの意味がわかりやすくなることです。

たとえば、次のコードを見てみましょう。

C#
if (score >= 80)
{
Console.WriteLine("合格");
}

この80だけを見ると、「なぜ80なのか」が少しわかりにくいです。

そこで、constを使うと意味が明確になります。

C#
const int PassingScore = 80;

if (score >= PassingScore)
{
Console.WriteLine("合格");
}

PassingScoreという名前があることで、「80は合格点を表している」とすぐに理解できます。

ただし、constには注意点もあります。

constはコンパイル時に値が埋め込まれるため、あとから値を変更する可能性があるものには向いていません。特に、外部に公開するライブラリでpublic constを使う場合は注意が必要です。

2. C# constの基本的な使い方

2-1. constの基本構文

C#でconstを使う基本構文は次のとおりです。

C#
const 型名 定数名 = ;

たとえば、整数の定数を宣言する場合は次のように書きます。

C#
const int MaxUsers = 100;

文字列の定数なら、次のように書きます。

C#
const string AppName = "MyApplication";

constでは、必ず宣言時に値を代入する必要があります。

次のコードはエラーです。

C#
const int MaxUsers; // エラー

constは、あとから値を代入できないため、宣言と同時に値を決めなければなりません。

2-2. 数値をconstで宣言する例

数値の固定値には、constがよく使われます。

C#
const int MaxRetryCount = 3;
const double TaxRate = 0.10;
const decimal ShippingFee = 500m;

Console.WriteLine(MaxRetryCount);
Console.WriteLine(TaxRate);
Console.WriteLine(ShippingFee);

このように、最大回数、税率、手数料などの固定値に名前を付けておくと、コードの意味がわかりやすくなります。

ただし、消費税率のように将来的に変更される可能性がある値は、constよりもreadonlyや設定ファイルで管理したほうがよい場合もあります。

2-3. 文字列をconstで宣言する例

文字列もconstで宣言できます。

C#
const string AppName = "CustomerManagement";
const string ErrorMessage = "エラーが発生しました。";
const string DateFormat = "yyyy/MM/dd";

Console.WriteLine(AppName);
Console.WriteLine(ErrorMessage);
Console.WriteLine(DateFormat);

メッセージ、フォーマット文字列、固定のキー名などは、const stringとして定義されることが多いです。

たとえば、同じエラーメッセージを複数箇所で使う場合、毎回文字列を直接書くよりも、constで定義しておくほうが保守しやすくなります。

C#
const string RequiredNameMessage = "名前は必須です。";

Console.WriteLine(RequiredNameMessage);

2-4. クラス内でconstを使う例

constはクラス内に定義できます。

C#
class MathConstants
{
public const double Pi = 3.14159;
public const int MaxValue = 100;
}

クラス内に定義したconstは、クラス名を使って参照できます。

C#
Console.WriteLine(MathConstants.Pi);
Console.WriteLine(MathConstants.MaxValue);

public constにすると、クラスの外部からも参照できます。

一方、クラス内部だけで使いたい場合は、private constにします。

C#
class UserValidator
{
private const int MinPasswordLength = 8;

public bool IsValidPassword(string password)
{
return password.Length >= MinPasswordLength;
}
}

このように、クラス内で使う固定値をprivate constにすると、マジックナンバーを減らせます。

2-5. メソッド内でconstを使う例

constはメソッド内でも使えます。

C#
void PrintResult(int score)
{
const int PassingScore = 80;

if (score >= PassingScore)
{
Console.WriteLine("合格");
}
else
{
Console.WriteLine("不合格");
}
}

メソッド内だけで使う固定値であれば、メソッド内にconstを定義しても問題ありません。

ただし、複数のメソッドで同じ定数を使う場合は、クラス内のフィールドとして定義したほうが管理しやすくなります。

C#
class ScoreChecker
{
private const int PassingScore = 80;

public bool IsPassed(int score)
{
return score >= PassingScore;
}

public void PrintResult(int score)
{
Console.WriteLine(IsPassed(score) ? "合格" : "不合格");
}
}

2-6. constは暗黙的にstatic扱いになる

constは暗黙的にstatic扱いになります。

そのため、次のようにインスタンスを作らずにクラス名から参照できます。

C#
class AppSettings
{
public const string AppName = "SampleApp";
}

Console.WriteLine(AppSettings.AppName);

一方で、constに明示的にstaticを付けることはできません。

C#
class AppSettings
{
public static const string AppName = "SampleApp"; // エラー
}

const自体が静的な定数として扱われるため、static constとは書かない点に注意しましょう。

正しくは次のように書きます。

C#
class AppSettings
{
public const string AppName = "SampleApp";
}

3. constで使える型・使えない型

3-1. constに指定できる型一覧

C#のconstで使える型は限られています。

主に、次のような型をconstにできます。

C#
const bool IsEnabled = true;
const byte ByteValue = 1;
const sbyte SByteValue = -1;
const short ShortValue = 10;
const ushort UShortValue = 10;
const int IntValue = 100;
const uint UIntValue = 100u;
const long LongValue = 1000L;
const ulong ULongValue = 1000UL;
const char Character = 'A';
const float FloatValue = 1.5f;
const double DoubleValue = 3.14;
const decimal DecimalValue = 100.5m;
const string Text = "Hello";

また、enumの値も定数として扱えます。

C#
enum UserRole
{
Admin,
Member,
Guest
}

一方、DateTime、配列、List<T>、通常のオブジェクトなどはconstにできません。

3-2. int・double・bool・char・stringの使用例

代表的な型の使用例を見てみましょう。

C#
const int MaxCount = 10;
const double Pi = 3.14159;
const bool IsDebugMode = false;
const char Separator = ',';
const string AppName = "SampleApp";

Console.WriteLine(MaxCount);
Console.WriteLine(Pi);
Console.WriteLine(IsDebugMode);
Console.WriteLine(Separator);
Console.WriteLine(AppName);

intdoubleは数値の固定値に使えます。

boolは、固定のフラグ値として使えます。

charは、区切り文字などに使えます。

stringは、固定メッセージやキー名に使えます。

C#
const string UserNameKey = "user_name";
const string DefaultMessage = "処理が完了しました。";

3-3. DateTimeや配列をconstにできない理由

DateTimeconstにできません。

C#
const DateTime StartDate = new DateTime(2026, 1, 1); // エラー

理由は、constにできる値はコンパイル時に決まる必要があるからです。

new DateTime(2026, 1, 1)はオブジェクトを生成する処理です。これは実行時に評価されるため、constにはできません。

配列も同じです。

C#
const int[] Numbers = { 1, 2, 3 }; // エラー

配列は参照型のオブジェクトであり、実行時に生成されます。そのため、constでは宣言できません。

このような場合は、readonlystatic readonlyを使います。

C#
static readonly DateTime StartDate = new DateTime(2026, 1, 1);

static readonly int[] Numbers = { 1, 2, 3 };

ただし、配列をreadonlyにしても、配列の中身までは完全に変更不可になるわけではありません。

C#
static readonly int[] Numbers = { 1, 2, 3 };

Numbers[0] = 100; // これは可能

配列の参照先は変更できませんが、配列の要素は変更できます。完全に変更不可にしたい場合は、読み取り専用コレクションなどを検討します。

3-4. nullをconstにできるケース

constでは、stringnullを指定できます。

C#
const string DefaultName = null;

これは有効です。

一方で、通常のオブジェクト型をconstにすることはできません。

C#
const object Value = null; // エラーになる場合がある

基本的には、constnullを扱う場面は多くありません。実務では、const stringに対してnullを指定するよりも、空文字や明確な既定値を使うことが多いです。

C#
const string DefaultName = "";

ただし、nullに特別な意味を持たせたい場合には、const stringnullを定義することも可能です。

3-5. enumとconstの関係

enumは、名前付きの定数をまとめて定義する仕組みです。

C#
enum OrderStatus
{
Pending,
Shipped,
Delivered,
Canceled
}

このように定義すると、数値ではなく意味のある名前で状態を表せます。

C#
OrderStatus status = OrderStatus.Shipped;

if (status == OrderStatus.Shipped)
{
Console.WriteLine("発送済みです。");
}

enumの各メンバーは定数として扱われます。

明示的に値を指定することもできます。

C#
enum ErrorCode
{
None = 0,
NotFound = 404,
ServerError = 500
}

複数の関連する定数を管理したい場合、const intをたくさん並べるよりも、enumを使ったほうがわかりやすいことがあります。

C#
const int StatusPending = 0;
const int StatusShipped = 1;
const int StatusDelivered = 2;

より良い例は次のようになります。

C#
enum Status
{
Pending,
Shipped,
Delivered
}

4. C# constとreadonlyの違い

4-1. constとreadonlyの最大の違いは「値が決まるタイミング」

constreadonlyは、どちらも「あとから変更しにくい値」を扱うために使われます。

しかし、最大の違いは値が決まるタイミングです。

constはコンパイル時に値が決まります。

C#
const int MaxCount = 10;

readonlyは実行時に値を設定できます。

C#
readonly DateTime CreatedAt;

public Sample()
{
CreatedAt = DateTime.Now;
}

この違いが、constreadonlyの使い分けで最も重要です。

4-2. constはコンパイル時定数、readonlyは実行時に設定可能

constはコンパイル時定数です。

そのため、次のように、コード上で値が確定している必要があります。

C#
const int MaxCount = 10;
const string AppName = "SampleApp";

一方、readonlyは実行時に値を決められます。

C#
readonly DateTime StartTime;

public Program()
{
StartTime = DateTime.Now;
}

DateTime.Nowは実行時に決まる値なので、constにはできません。しかし、readonlyなら使えます。

C#
readonly Guid Id;

public Program()
{
Id = Guid.NewGuid();
}

このように、実行時に生成される値を変更不可にしたい場合は、readonlyを使います。

4-3. readonlyはコンストラクタで代入できる

readonlyフィールドは、宣言時またはコンストラクタ内で代入できます。

C#
class User
{
private readonly string name;

public User(string name)
{
this.name = name;
}

public void PrintName()
{
Console.WriteLine(name);
}
}

この例では、nameはコンストラクタで代入されています。

一度オブジェクトが作られた後は、nameを変更できません。

C#
class User
{
private readonly string name;

public User(string name)
{
this.name = name;
}

public void ChangeName(string newName)
{
name = newName; // エラー
}
}

このように、オブジェクト生成時に決まる値にはreadonlyが向いています。

4-4. constとreadonlyのコード比較

constreadonlyの違いをコードで比較してみましょう。

C#
class Sample
{
public const int MaxCount = 10;

public readonly DateTime CreatedAt;

public Sample()
{
CreatedAt = DateTime.Now;
}
}

MaxCountはコンパイル時に決まる固定値です。

C#
Console.WriteLine(Sample.MaxCount);

constは暗黙的に静的メンバーとして扱われるため、クラス名から参照できます。

一方、CreatedAtはインスタンスごとに異なる値を持てます。

C#
Sample sample1 = new Sample();
Sample sample2 = new Sample();

Console.WriteLine(sample1.CreatedAt);
Console.WriteLine(sample2.CreatedAt);

readonlyはインスタンスごとに値を持てるため、オブジェクトごとに異なる初期値を設定したい場合に便利です。

4-5. static readonlyとの違い

static readonlyは、クラスに属する読み取り専用フィールドです。

C#
class AppSettings
{
public static readonly DateTime StartDate = DateTime.Now;
}

static readonlyは、constのようにクラス名から参照できます。

C#
Console.WriteLine(AppSettings.StartDate);

しかし、constとは違い、実行時に値を設定できます。

C#
class AppSettings
{
public static readonly Guid ApplicationId = Guid.NewGuid();
}

Guid.NewGuid()は実行時に値が決まるため、constにはできません。しかし、static readonlyなら使えます。

また、配列やオブジェクトもstatic readonlyで保持できます。

C#
class AppSettings
{
public static readonly string[] SupportedLanguages = { "ja", "en" };
}

ただし、参照型の場合は中身の変更に注意が必要です。

C#
AppSettings.SupportedLanguages[0] = "fr"; // 配列の中身は変更できる

4-6. const・readonly・static readonlyの使い分け早見表

constreadonlystatic readonlyの使い分けは次のように考えるとわかりやすいです。

種類値が決まるタイミング参照方法主な用途
constコンパイル時クラス名から参照完全に固定された値
readonly実行時インスタンスから参照オブジェクトごとに異なる変更不可の値
static readonly実行時クラス名から参照クラス全体で共有する変更不可の値

たとえば、円周率のように変わらない値にはconstが向いています。

C#
public const double Pi = 3.14159;

ユーザーごとに異なるIDにはreadonlyが向いています。

C#
public readonly Guid UserId;

アプリケーション起動時に決まる値にはstatic readonlyが向いています。

C#
public static readonly DateTime StartedAt = DateTime.Now;

5. constを使うべき場面・使わないほうがよい場面

5-1. 固定値・変更予定のない値にはconstが向いている

constは、将来的にも変更される可能性がほとんどない固定値に向いています。

たとえば、次のような値です。

C#
const double Pi = 3.14159;
const int MonthsInYear = 12;
const int DaysInWeek = 7;
const string NewLine = "\n";

このような値は、プログラムの実行環境や日時によって変わりません。

また、アプリケーション内だけで使う固定メッセージやキー名にも使えます。

C#
private const string UserNameKey = "user_name";
private const string ErrorMessage = "入力値が正しくありません。";

変更予定がなく、コンパイル時に値が決まるものは、constのよい使いどころです。

5-2. 消費税率や設定値にconstを使うべきか

消費税率のような値をconstにすべきかは、慎重に考える必要があります。

C#
const decimal TaxRate = 0.10m;

一見すると問題なさそうですが、税率は将来的に変更される可能性があります。

アプリケーションを再コンパイルして配布し直せる小規模なプログラムなら、constでも問題ない場合があります。

しかし、実務では税率や手数料、しきい値などは、設定ファイルやデータベースで管理することも多いです。

C#
decimal taxRate = configuration.GetValue<decimal>("TaxRate");

また、コード上で管理する場合でも、将来変更される可能性があるならstatic readonlyを検討できます。

C#
public static readonly decimal TaxRate = 0.10m;

「今は固定値だが、将来変わるかもしれない値」は、安易にconstにしないほうが安全です。

5-3. 外部公開ライブラリでconstを使う際の注意点

外部に公開するライブラリでpublic constを使う場合は注意が必要です。

たとえば、ライブラリ側に次の定数があるとします。

C#
public class LibrarySettings
{
public const int MaxCount = 10;
}

別のアプリケーションがこの定数を参照していた場合、コンパイル時に10という値が呼び出し側に埋め込まれることがあります。

その後、ライブラリ側で値を変更したとします。

C#
public class LibrarySettings
{
public const int MaxCount = 20;
}

しかし、呼び出し側のアプリケーションを再コンパイルしないと、古い値の10を使い続ける可能性があります。

このような問題を避けるため、外部公開する値で将来変更される可能性がある場合は、public constではなくpublic static readonlyを使うことを検討します。

C#
public class LibrarySettings
{
public static readonly int MaxCount = 20;
}

5-4. 後から変更される可能性がある値はreadonlyを検討する

後から変更される可能性がある値や、実行時に決まる値にはreadonlyまたはstatic readonlyを検討しましょう。

たとえば、アプリケーションの開始時刻はconstにできません。

C#
public static readonly DateTime StartedAt = DateTime.Now;

ユーザーIDのようにインスタンスごとに異なる値もreadonlyが向いています。

C#
class User
{
public readonly Guid Id;

public User()
{
Id = Guid.NewGuid();
}
}

設定値をコード内に固定したい場合でも、将来変更される可能性があるなら、constよりもstatic readonlyのほうが適していることがあります。

C#
public static readonly int MaxRetryCount = 3;

5-5. マジックナンバーをconstで改善する方法

マジックナンバーとは、コード内に直接書かれた意味のわかりにくい数値のことです。

C#
if (password.Length < 8)
{
Console.WriteLine("パスワードが短すぎます。");
}

この8だけを見ると、「なぜ8なのか」がコードからはわかりにくいです。

constを使うと、意味を明確にできます。

C#
const int MinPasswordLength = 8;

if (password.Length < MinPasswordLength)
{
Console.WriteLine("パスワードが短すぎます。");
}

さらに、複数箇所で同じ値を使っている場合、定数にしておけば変更時の修正箇所を減らせます。

C#
class PasswordValidator
{
private const int MinPasswordLength = 8;

public bool IsValid(string password)
{
return password.Length >= MinPasswordLength;
}
}

このように、constはコードの意味を明確にし、保守しやすくするために役立ちます。

6. C# constでよくあるエラーと対策

6-1. 「代入式は定数である必要があります」の原因と対策

constでよくあるエラーのひとつが、「代入式は定数である必要があります」という内容のエラーです。

たとえば、次のコードはエラーになります。

C#
int value = 10;
const int MaxValue = value; // エラー

valueは変数です。たとえ中身が10だとしても、コンパイル時定数ではありません。

constに代入できるのは、コンパイル時に値が決まる式だけです。

正しくは、次のように直接値を指定します。

C#
const int MaxValue = 10;

また、他のconstを使った式は有効です。

C#
const int BaseValue = 10;
const int MaxValue = BaseValue * 2;

この場合、BaseValue * 2はコンパイル時に計算できるため、constにできます。

6-2. DateTimeをconstにできない場合の対策

DateTimeconstにしようとするとエラーになります。

C#
const DateTime StartDate = new DateTime(2026, 1, 1); // エラー

DateTimeは構造体ですが、constで扱える型ではありません。また、new DateTime(...)は実行時に評価されるため、コンパイル時定数にはなりません。

この場合は、static readonlyを使います。

C#
static readonly DateTime StartDate = new DateTime(2026, 1, 1);

インスタンスごとに異なる日付を持たせたい場合は、readonlyを使います。

C#
class Campaign
{
public readonly DateTime StartDate;

public Campaign(DateTime startDate)
{
StartDate = startDate;
}
}

日付を文字列として固定したい場合は、const stringにする方法もあります。

C#
const string StartDateText = "2026-01-01";

ただし、この場合はあくまで文字列であり、日付計算にはそのまま使えません。

6-3. 配列・List・オブジェクトをconstにできない理由

配列、List<T>、通常のオブジェクトはconstにできません。

C#
const int[] Numbers = { 1, 2, 3 }; // エラー
const List<string> Names = new List<string>(); // エラー
const object Value = new object(); // エラー

これらは実行時に生成される参照型のオブジェクトだからです。

このような場合は、static readonlyを使います。

C#
static readonly int[] Numbers = { 1, 2, 3 };

static readonly List<string> Names = new List<string>
{
"Alice",
"Bob"
};

ただし、static readonlyにしても、参照先のオブジェクトの中身が変更できる場合があります。

C#
Numbers[0] = 100;
Names.Add("Charlie");

完全に変更させたくない場合は、読み取り専用コレクションを使うことを検討します。

C#
static readonly IReadOnlyList<string> Names = new List<string>
{
"Alice",
"Bob"
};

さらに厳密に管理したい場合は、外部から変更できない形で公開する設計が必要です。

6-4. constに後から値を代入しようとした場合のエラー

constは宣言時に値を決める必要があり、後から代入できません。

C#
const int MaxCount = 10;
MaxCount = 20; // エラー

これは、constが変更不可の定数だからです。

もし値を変更する必要があるなら、constではなく通常の変数を使います。

C#
int maxCount = 10;
maxCount = 20;

一度だけ初期化して、その後は変更したくない場合はreadonlyを使います。

C#
readonly int maxCount;

public Sample(int value)
{
maxCount = value;
}

クラス全体で共有し、実行時に初期化したい場合はstatic readonlyを使います。

C#
static readonly int MaxCount = 10;

6-5. constとstaticを一緒に書いたときのエラー

C#では、conststaticを明示的に付けることはできません。

C#
public static const int MaxCount = 10; // エラー

constは暗黙的に静的メンバーとして扱われます。そのため、staticを書く必要がありません。

正しくは次のように書きます。

C#
public const int MaxCount = 10;

クラス名から参照できます。

C#
Console.WriteLine(Sample.MaxCount);

もしstaticを使いたい場合は、constではなくstatic readonlyを使います。

C#
public static readonly int MaxCount = 10;

6-6. エラーをreadonlyやstatic readonlyで解決する方法

constでエラーが出た場合、多くは「コンパイル時に値が決まらないものを指定している」ことが原因です。

たとえば、次のコードはエラーです。

C#
const DateTime Now = DateTime.Now; // エラー

この場合はstatic readonlyにします。

C#
static readonly DateTime Now = DateTime.Now;

配列もconstにはできません。

C#
const string[] Languages = { "C#", "Java", "Python" }; // エラー

この場合もstatic readonlyを使います。

C#
static readonly string[] Languages = { "C#", "Java", "Python" };

インスタンスごとに値を変えたい場合はreadonlyを使います。

C#
class User
{
public readonly string Name;

public User(string name)
{
Name = name;
}
}

constでエラーが出たときは、「この値は本当にコンパイル時に決まるのか?」を確認しましょう。実行時に決まる値なら、readonlystatic readonlyを使うのが基本です。

7. constの実践的なコード例

7-1. 定数クラスでconstを管理する例

アプリケーション全体で使う固定値は、定数クラスにまとめることがあります。

C#
public static class AppConstants
{
public const string AppName = "TaskManager";
public const int MaxTaskCount = 100;
public const string DefaultDateFormat = "yyyy/MM/dd";
}

使う側は、クラス名から参照します。

C#
Console.WriteLine(AppConstants.AppName);
Console.WriteLine(AppConstants.MaxTaskCount);
Console.WriteLine(AppConstants.DefaultDateFormat);

ただし、何でもひとつの定数クラスに詰め込むと、逆に管理しづらくなることがあります。

たとえば、ユーザー関連、注文関連、画面表示関連など、用途ごとに分けると見通しがよくなります。

C#
public static class UserConstants
{
public const int MinPasswordLength = 8;
public const int MaxUserNameLength = 50;
}

public static class MessageConstants
{
public const string RequiredName = "名前は必須です。";
public const string InvalidEmail = "メールアドレスの形式が正しくありません。";
}

7-2. メッセージ文字列をconstで定義する例

同じメッセージを複数箇所で使う場合は、const stringとして定義すると便利です。

C#
class Messages
{
public const string SaveCompleted = "保存が完了しました。";
public const string DeleteCompleted = "削除が完了しました。";
public const string UnexpectedError = "予期しないエラーが発生しました。";
}

使用例は次のとおりです。

C#
Console.WriteLine(Messages.SaveCompleted);

メッセージを直接書く場合と比べて、修正箇所を一元化できます。

C#
Console.WriteLine("保存が完了しました。");
Console.WriteLine("保存が完了しました。");
Console.WriteLine("保存が完了しました。");

このように同じ文字列が何度も登場する場合、constでまとめておくと保守しやすくなります。

C#
Console.WriteLine(Messages.SaveCompleted);
Console.WriteLine(Messages.SaveCompleted);
Console.WriteLine(Messages.SaveCompleted);

7-3. 計算式でconstを使う例

constは計算式でも使えます。

C#
const int BasePrice = 1000;
const int Quantity = 3;
const int TotalPrice = BasePrice * Quantity;

Console.WriteLine(TotalPrice);

BasePriceQuantityがどちらもconstなので、TotalPriceもコンパイル時に計算できます。

円の面積を求める例も見てみましょう。

C#
const double Pi = 3.14159;
const double Radius = 5.0;
const double Area = Pi * Radius * Radius;

Console.WriteLine(Area);

このように、固定値同士の計算結果もconstとして定義できます。

ただし、変数を含む計算はconstにはできません。

C#
int radius = 5;
const double Area = 3.14159 * radius * radius; // エラー

radiusは実行時の変数なので、コンパイル時に値が決まりません。

7-4. switch文や属性でconstを使う例

constswitch文のcaseラベルで使えます。

C#
const int StatusActive = 1;
const int StatusInactive = 2;

int status = 1;

switch (status)
{
case StatusActive:
Console.WriteLine("有効です。");
break;

case StatusInactive:
Console.WriteLine("無効です。");
break;
}

caseラベルにはコンパイル時定数が必要です。そのため、constが使えます。

また、属性の引数にもconstを使える場合があります。

C#
class RouteNames
{
public const string Home = "home";
}

[Obsolete("このメソッドは古くなりました。")]
void OldMethod()
{
}

属性の引数には、コンパイル時に決まる値が必要です。そのため、固定文字列を使う場合はconst stringが役立ちます。

C#
class Messages
{
public const string ObsoleteMessage = "このメソッドは古くなりました。";
}

class Sample
{
[Obsolete(Messages.ObsoleteMessage)]
public void OldMethod()
{
}
}

7-5. constを使って可読性を高めるサンプル

constを使うと、コードの意図がわかりやすくなります。

まず、constを使わない例です。

C#
class DiscountService
{
public int Calculate(int price)
{
if (price >= 10000)
{
return price - 1000;
}

return price;
}
}

このコードでは、100001000の意味がすぐにはわかりません。

constを使うと、次のように改善できます。

C#
class DiscountService
{
private const int DiscountThreshold = 10000;
private const int DiscountAmount = 1000;

public int Calculate(int price)
{
if (price >= DiscountThreshold)
{
return price - DiscountAmount;
}

return price;
}
}

DiscountThresholdは割引対象になる金額、DiscountAmountは割引額だとわかります。

このように、意味のある名前を付けることで、コメントを書かなくても意図が伝わりやすいコードになります。

8. constを使うときの命名規則とベストプラクティス

8-1. C#におけるconstの一般的な命名ルール

C#では、constの名前には一般的にPascalCaseが使われます。

C#
const int MaxRetryCount = 3;
const string DefaultUserName = "Guest";
const double TaxRate = 0.10;

PascalCaseとは、各単語の先頭を大文字にする書き方です。

C#
MaxRetryCount
DefaultUserName
ApplicationName

C#では、クラス名、メソッド名、プロパティ名、定数名などでPascalCaseがよく使われます。

8-2. PascalCaseとUPPER_CASEのどちらを使うべきか

他の言語では、定数名をすべて大文字で書くことがあります。

C#
const int MAX_RETRY_COUNT = 3;

これはUPPER_CASESNAKE_CASEと呼ばれる書き方です。

C#でも絶対に禁止というわけではありませんが、一般的なC#のスタイルではPascalCaseが使われることが多いです。

C#
const int MaxRetryCount = 3;

プロジェクトやチームで命名規則が決まっている場合は、そのルールに従いましょう。

既存のコードがUPPER_CASEで統一されているなら、それに合わせることもあります。

重要なのは、プロジェクト全体で一貫性を保つことです。

8-3. 意味のある定数名を付けるコツ

constを使うときは、値そのものではなく、意味が伝わる名前を付けることが大切です。

悪い例です。

C#
const int Number = 80;
const string Text = "エラー";

これでは、何の数値なのか、何の文字列なのかがわかりません。

良い例は次のようになります。

C#
const int PassingScore = 80;
const string ValidationErrorMessage = "入力値が正しくありません。";

定数名を付けるときは、次のような点を意識します。

C#
const int MaxLoginAttempts = 5;
const int MinPasswordLength = 8;
const string RequiredEmailMessage = "メールアドレスは必須です。";

「最大値なのか」「最小値なのか」「何のメッセージなのか」が名前からわかるようにすると、コードの可読性が高まります。

8-4. public constとprivate constの使い分け

constにはアクセス修飾子を付けられます。

クラス内部だけで使う場合は、private constを使います。

C#
class PasswordValidator
{
private const int MinPasswordLength = 8;

public bool IsValid(string password)
{
return password.Length >= MinPasswordLength;
}
}

外部から参照させたい場合は、public constを使います。

C#
public class AppConstants
{
public const string AppName = "SampleApp";
}

ただし、public constは外部に公開される値です。将来変更される可能性がある値には注意が必要です。

外部公開する値で、後から変更される可能性がある場合は、public static readonlyを検討します。

C#
public class AppConstants
{
public static readonly int MaxRetryCount = 3;
}

基本的には、必要以上にpublic constを増やさず、クラス内部で使う値はprivate constにするのがおすすめです。

8-5. 保守しやすい定数管理のポイント

保守しやすい定数管理のポイントは、定数の置き場所を適切に分けることです。

すべての定数をひとつの巨大なクラスにまとめると、どこに何があるのかわかりにくくなります。

C#
public static class Constants
{
public const int MinPasswordLength = 8;
public const string OrderStatusPending = "Pending";
public const string ErrorMessage = "エラーが発生しました。";
public const int MaxProductNameLength = 100;
}

このように雑多にまとめるより、用途ごとに分けるほうが管理しやすくなります。

C#
public static class UserConstants
{
public const int MinPasswordLength = 8;
public const int MaxUserNameLength = 50;
}

public static class OrderConstants
{
public const string StatusPending = "Pending";
public const string StatusCompleted = "Completed";
}

public static class MessageConstants
{
public const string UnexpectedError = "エラーが発生しました。";
}

また、そのクラスでしか使わない定数は、そのクラスの中にprivate constとして置くとよいです。

C#
class ProductValidator
{
private const int MaxProductNameLength = 100;

public bool IsValidName(string name)
{
return name.Length <= MaxProductNameLength;
}
}

定数は「どこから使われるのか」「将来変更される可能性があるのか」を考えて配置しましょう。

9. C# constに関するよくある質問

9-1. constはstaticと同じですか?

constは暗黙的にstaticのように扱われますが、staticと完全に同じではありません。

constはコンパイル時定数であり、宣言時に値を決める必要があります。

C#
public const int MaxCount = 10;

staticフィールドは、実行時に値を変更できます。

C#
public static int Count = 0;

Count = 10;

static readonlyなら、クラスに属する読み取り専用の値を実行時に設定できます。

C#
public static readonly DateTime StartedAt = DateTime.Now;

また、constには明示的にstaticを付けられません。

C#
public static const int MaxCount = 10; // エラー

正しくは次のように書きます。

C#
public const int MaxCount = 10;

9-2. constと#defineの違いは何ですか?

C#のconstは、値を持つ定数を定義するために使います。

C#
const int MaxCount = 10;

一方、#defineはプリプロセッサシンボルを定義するために使います。

C#
#define DEBUG_MODE

#defineは、数値や文字列の定数を定義するためのものではありません。条件付きコンパイルなどで使われます。

C#
#if DEBUG_MODE
Console.WriteLine("デバッグモードです。");
#endif

CやC++では#defineで定数を定義することがありますが、C#では通常、値を表す定数にはconstを使います。

9-3. constにDateTimeを指定できないのはなぜですか?

DateTimeconstにできません。

C#
const DateTime StartDate = new DateTime(2026, 1, 1); // エラー

理由は、constにできる値はコンパイル時に決まる必要があるからです。

new DateTime(...)は実行時に評価されるため、constにはできません。

代わりに、static readonlyを使います。

C#
static readonly DateTime StartDate = new DateTime(2026, 1, 1);

日付を文字列として固定するだけなら、const stringを使う方法もあります。

C#
const string StartDateText = "2026-01-01";

ただし、日付計算を行う場合はDateTimeとして扱うほうが適しています。

9-4. constとreadonlyはどちらを使えばいいですか?

完全に固定されていて、コンパイル時に値が決まるものにはconstを使います。

C#
const int DaysInWeek = 7;
const string DefaultDateFormat = "yyyy/MM/dd";

実行時に値が決まるもの、または将来変更される可能性があるものにはreadonlystatic readonlyを使います。

C#
readonly Guid UserId;

public User()
{
UserId = Guid.NewGuid();
}

クラス全体で共有する実行時の固定値にはstatic readonlyが向いています。

C#
static readonly DateTime ApplicationStartedAt = DateTime.Now;

迷った場合は、「この値はコンパイル時に完全に決まるか」「将来変更される可能性がないか」を基準に考えましょう。

9-5. constはパフォーマンスに影響しますか?

constはコンパイル時に値が決まるため、実行時に値を取得する負荷はほとんどありません。

たとえば、次のような定数は、コンパイル時に値として扱われます。

C#
const int MaxCount = 10;

ただし、通常のアプリケーション開発では、constを使う主な目的はパフォーマンス向上ではなく、可読性と保守性の向上です。

C#
if (count > MaxCount)
{
Console.WriteLine("上限を超えています。");
}

このように、値に意味のある名前を付けることで、コードの意図が伝わりやすくなります。

パフォーマンスを理由に無理にconstを使うよりも、変更可能性や設計上の意味を考えて使い分けることが大切です。

9-6. stringをconstにしても問題ありませんか?

固定の文字列であれば、stringconstにして問題ありません。

C#
const string AppName = "SampleApp";
const string ErrorMessage = "エラーが発生しました。";
const string DateFormat = "yyyy/MM/dd";

メッセージ、キー名、フォーマット文字列などは、const stringとしてよく使われます。

ただし、外部公開ライブラリでpublic const stringを使う場合は注意が必要です。値を変更しても、参照側を再コンパイルしないと古い値が使われる可能性があります。

将来変更される可能性がある文字列なら、static readonlyを検討しましょう。

C#
public static readonly string AppName = "SampleApp";

また、多言語対応するメッセージや、設定ファイルで変更したい文字列は、constではなくリソースファイルや設定値で管理するほうが適しています。

まとめ

C#のconstは、変更できない定数を宣言するためのキーワードです。

C#
const int MaxCount = 10;
const string AppName = "SampleApp";

constの重要なポイントは、値がコンパイル時に決まることです。数値、文字、文字列、真偽値など、コンパイル時に確定できる値に使えます。

一方で、DateTime、配列、List<T>、オブジェクトなどはconstにできません。これらを変更不可に近い形で扱いたい場合は、readonlystatic readonlyを使います。

constreadonlyの違いは、値が決まるタイミングです。

C#
const int MaxCount = 10;

readonly DateTime CreatedAt;

public Sample()
{
CreatedAt = DateTime.Now;
}

constはコンパイル時、readonlyは実行時に値を設定できます。

また、constは暗黙的にstatic扱いになるため、static constとは書けません。

C#
public const int MaxCount = 10;

変更される可能性がない固定値にはconst、実行時に決まる値や将来変更される可能性がある値にはreadonlyまたはstatic readonlyを使うのが基本です。

constを適切に使うと、マジックナンバーを減らし、コードの意味を明確にできます。

C#
private const int MinPasswordLength = 8;

C#で読みやすく保守しやすいコードを書くために、constreadonlystatic readonlyの違いを理解し、場面に応じて使い分けましょう。