C#のcase文の使い方を基礎から解説|switch文で条件分岐を迷わず書く方法
はじめに
C#で条件分岐を書くときによく使われるのが、switch文とcase文です。
たとえば、「入力された番号によって処理を変えたい」「ステータスごとに表示するメッセージを変えたい」「曜日や種類ごとに処理を分けたい」といった場面では、if文よりもswitch-case文のほうが読みやすくなることがあります。
この記事では、C#のcase文の基本から、複数条件、when、範囲条件、switch式、パターンマッチングまで、初心者にもわかりやすく解説します。
「csharp case」と検索して、C#のcaseの書き方や使いどころを知りたい方は、まずこの記事の基本構文から順番に確認していきましょう。
1. C#のcase文とは?switch文で条件分岐を書くための基本
C#のcase文は、switch文の中で使う条件分岐のための構文です。
ある値を確認し、その値が特定の値と一致した場合に、それぞれ対応する処理を実行できます。
たとえば、数値が1なら「開始」、2なら「設定」、3なら「終了」のように、値ごとに処理を分けたい場合に便利です。
C#int menu = 1;
switch (menu)
{
case 1:
Console.WriteLine("開始します");
break;
case 2:
Console.WriteLine("設定を開きます");
break;
case 3:
Console.WriteLine("終了します");
break;
default:
Console.WriteLine("不明なメニューです");
break;
}
このように、switch文の中でcaseを使うことで、値に応じた処理を整理して書くことができます。
1-1. case文はswitch文の中で条件ごとの処理を分ける仕組み
case文は単独では使えません。
必ずswitch文の中で使います。
C#switch (調べたい値)
{
case 値1:
// 値1に一致したときの処理
break;
case 値2:
// 値2に一致したときの処理
break;
default:
// どのcaseにも一致しなかったときの処理
break;
}
switchの丸かっこ内に判定したい値を書き、caseには一致させたい値を書きます。
switchの値とcaseの値が一致すると、そのcase内の処理が実行されます。
1-2. if文との違いとswitch文が向いている場面
C#の条件分岐にはif文もあります。
if文は、条件式を自由に書けるのが特徴です。
C#int score = 85;
if (score >= 80)
{
Console.WriteLine("合格です");
}
else
{
Console.WriteLine("不合格です");
}
一方、switch-case文は、主に「1つの値に対して、複数の候補から一致するものを探す」場合に向いています。
C#string role = "Admin";
switch (role)
{
case "Admin":
Console.WriteLine("管理者です");
break;
case "User":
Console.WriteLine("一般ユーザーです");
break;
case "Guest":
Console.WriteLine("ゲストです");
break;
default:
Console.WriteLine("不明な権限です");
break;
}
if文でも同じことは書けますが、比較対象が同じ値で、候補が複数ある場合は、switch-case文のほうが見通しがよくなります。
1-3. 「csharp case」で検索する人がまず知りたいポイント
「csharp case」で検索する人がまず押さえるべきポイントは、次のとおりです。
C#のcaseは、switch文の中で使います。
caseには、基本的に比較したい値を書きます。
各caseの処理の最後には、通常breakを書きます。
どのcaseにも一致しない場合の処理は、defaultに書きます。
また、C#では他の言語と違い、原則としてcaseから次のcaseへ自然に処理が流れる「フォールスルー」はできません。
そのため、初心者はまず次の4つを覚えると理解しやすくなります。
C#switch
case
break
default
この4つの役割を理解すれば、C#の基本的なswitch-case文は書けるようになります。
2. C#のswitch-case文の基本構文
ここからは、C#のswitch-case文の基本構文を詳しく見ていきます。
2-1. switch・case・break・defaultの役割
switch文でよく使うキーワードには、次のような役割があります。
C#switch (value)
{
case 1:
Console.WriteLine("1です");
break;
case 2:
Console.WriteLine("2です");
break;
default:
Console.WriteLine("その他です");
break;
}
switchは、判定したい値を指定する部分です。
caseは、値が一致した場合の処理を定義する部分です。
breakは、そのcaseの処理が終わったらswitch文を抜けるために使います。
defaultは、どのcaseにも一致しなかった場合に実行される処理です。
2-2. 最小構成のサンプルコードで流れを理解する
最小構成のswitch-case文は、次のように書けます。
C#int number = 2;
switch (number)
{
case 1:
Console.WriteLine("numberは1です");
break;
case 2:
Console.WriteLine("numberは2です");
break;
}
この場合、numberの値は2です。
そのため、case 1は実行されず、case 2の処理が実行されます。
実行結果は次のようになります。
C#numberは2です
caseは上から順番に確認され、一致した場所の処理が実行されます。
2-3. caseに一致したときの処理の実行順
次のコードを見てみましょう。
C#int level = 3;
switch (level)
{
case 1:
Console.WriteLine("初級");
break;
case 2:
Console.WriteLine("中級");
break;
case 3:
Console.WriteLine("上級");
break;
default:
Console.WriteLine("不明");
break;
}
levelは3なので、case 3に一致します。
そのため、実行されるのは次の部分です。
C#case 3:
Console.WriteLine("上級");
break;
実行結果は次のとおりです。
C#上級
一致したcaseの中の処理が実行され、breakによってswitch文を抜けます。
2-4. どのcaseにも一致しない場合のdefaultの使い方
defaultは、どのcaseにも一致しなかったときの処理を書くために使います。
C#int menu = 9;
switch (menu)
{
case 1:
Console.WriteLine("新規作成");
break;
case 2:
Console.WriteLine("保存");
break;
case 3:
Console.WriteLine("終了");
break;
default:
Console.WriteLine("無効なメニュー番号です");
break;
}
この例では、menuの値は9です。
case 1、case 2、case 3のどれにも一致しないため、defaultが実行されます。
C#無効なメニュー番号です
defaultは必須ではありませんが、想定外の値を処理できるため、基本的には書いておくと安全です。
3. case文でよく使う値の種類
C#のcase文では、数値、文字列、enum、nullなどを扱えます。
3-1. 数値を使ったswitch-case文の書き方
数値を使ったswitch-case文は、初心者が最初に理解しやすい例です。
C#int day = 1;
switch (day)
{
case 1:
Console.WriteLine("月曜日");
break;
case 2:
Console.WriteLine("火曜日");
break;
case 3:
Console.WriteLine("水曜日");
break;
default:
Console.WriteLine("不明な曜日番号です");
break;
}
dayの値が1なら月曜日、2なら火曜日、3なら水曜日と表示されます。
数値コードやメニュー番号のように、番号ごとに処理を分けたいときに便利です。
3-2. 文字列を使ったswitch-case文の書き方
C#のswitch-case文では、文字列も扱えます。
C#string command = "start";
switch (command)
{
case "start":
Console.WriteLine("処理を開始します");
break;
case "stop":
Console.WriteLine("処理を停止します");
break;
case "restart":
Console.WriteLine("処理を再起動します");
break;
default:
Console.WriteLine("不明なコマンドです");
break;
}
この例では、commandが"start"なので、次のように表示されます。
C#処理を開始します
ユーザー入力、コマンド名、状態名などによって処理を分けたい場合に使いやすい書き方です。
ただし、文字列の比較では大文字・小文字の違いに注意が必要です。
C#string command = "Start";
このように先頭が大文字になっていると、case "start"には一致しません。
必要に応じて、あらかじめ小文字に変換してから比較するとよいでしょう。
C#string command = "Start".ToLower();
switch (command)
{
case "start":
Console.WriteLine("処理を開始します");
break;
}
3-3. enumを使って可読性の高い分岐を書く方法
enumを使うと、数値や文字列を直接書くよりも意味がわかりやすくなります。
C#enum OrderStatus
{
New,
Paid,
Shipped,
Canceled
}
このenumを使って、注文ステータスごとに処理を分けてみます。
C#OrderStatus status = OrderStatus.Paid;
switch (status)
{
case OrderStatus.New:
Console.WriteLine("新規注文です");
break;
case OrderStatus.Paid:
Console.WriteLine("支払い済みです");
break;
case OrderStatus.Shipped:
Console.WriteLine("発送済みです");
break;
case OrderStatus.Canceled:
Console.WriteLine("キャンセル済みです");
break;
default:
Console.WriteLine("不明な注文状態です");
break;
}
case 1やcase "paid"のように書くよりも、case OrderStatus.Paidのほうが意味が明確です。
業務ロジックでは、ステータスや種別をenumで表現すると、読みやすく保守しやすいコードになります。
3-4. nullをcaseで判定する方法
C#では、case nullを使ってnullを判定できます。
C#string? name = null;
switch (name)
{
case null:
Console.WriteLine("名前が入力されていません");
break;
case "admin":
Console.WriteLine("管理者です");
break;
default:
Console.WriteLine($"こんにちは、{name}さん");
break;
}
nameがnullの場合、case nullが実行されます。
C#名前が入力されていません
nullの可能性がある値を扱う場合は、case nullやdefaultを使って想定外の状態を処理しておくと安全です。
4. C#のcase文で複数条件を扱う方法
C#のcase文では、複数の値で同じ処理を実行したり、whenを使って追加条件を指定したりできます。
4-1. 複数のcaseを並べて同じ処理を実行する
複数のcaseで同じ処理を実行したい場合は、caseを連続して書けます。
C#int day = 6;
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
Console.WriteLine("平日です");
break;
case 6:
case 7:
Console.WriteLine("休日です");
break;
default:
Console.WriteLine("不明な曜日です");
break;
}
この例では、dayが1から5なら「平日です」、6または7なら「休日です」と表示されます。
複数のcaseを並べることで、同じ処理を重複して書かずに済みます。
4-2. caseでor条件を書く方法
C#の新しい書き方では、パターンマッチングを使ってor条件を書けます。
C#int day = 6;
switch (day)
{
case 6 or 7:
Console.WriteLine("休日です");
break;
case >= 1 and <= 5:
Console.WriteLine("平日です");
break;
default:
Console.WriteLine("不明な曜日です");
break;
}
case 6 or 7は、dayが6または7の場合に一致します。
従来の書き方では、次のように複数のcaseを並べていました。
C#case 6:
case 7:
Console.WriteLine("休日です");
break;
どちらも同じ意味ですが、単純なor条件ならcase 6 or 7のほうが短く書けます。
4-3. whenを使って追加条件を指定する方法
whenを使うと、caseに追加条件を指定できます。
C#int score = 85;
switch (score)
{
case int s when s >= 80:
Console.WriteLine("優秀です");
break;
case int s when s >= 60:
Console.WriteLine("合格です");
break;
default:
Console.WriteLine("不合格です");
break;
}
この例では、scoreが85なので、case int s when s >= 80に一致します。
C#優秀です
whenは、単純な値の一致だけでは表現しにくい条件を追加したいときに便利です。
4-4. 範囲条件を扱いたい場合の書き方
C#では、リレーショナルパターンを使って範囲条件を書けます。
C#int score = 72;
switch (score)
{
case >= 90:
Console.WriteLine("評価A");
break;
case >= 80:
Console.WriteLine("評価B");
break;
case >= 70:
Console.WriteLine("評価C");
break;
case >= 60:
Console.WriteLine("評価D");
break;
default:
Console.WriteLine("評価E");
break;
}
scoreは72なので、case >= 70に一致します。
C#評価C
このような範囲条件では、caseの順番が重要です。
たとえば、先にcase >= 60を書いてしまうと、90以上の点数もそこで一致してしまいます。
C#switch (score)
{
case >= 60:
Console.WriteLine("60点以上です");
break;
case >= 90:
Console.WriteLine("90点以上です");
break;
}
この場合、case >= 90は実質的に到達できない条件になります。
範囲条件を書くときは、より狭い条件や大きい値の条件を先に書くのが基本です。
5. case文を書くときに初心者がつまずきやすいポイント
C#のcase文は便利ですが、初心者がつまずきやすいルールもあります。
特に、break、フォールスルー、重複したcase、到達不能なcaseには注意が必要です。
5-1. breakを書き忘れるとどうなるのか
C#では、caseの処理が終わったら、通常はbreakを書いてswitch文を抜けます。
C#int number = 1;
switch (number)
{
case 1:
Console.WriteLine("1です");
break;
case 2:
Console.WriteLine("2です");
break;
}
もしbreakを書き忘れると、コンパイルエラーになることがあります。
C#int number = 1;
switch (number)
{
case 1:
Console.WriteLine("1です");
case 2:
Console.WriteLine("2です");
break;
}
このように、case 1の処理のあとにbreakがなく、次のcase 2へ処理が流れそうなコードは、C#では基本的に許可されません。
ただし、returnやthrowで処理が終了する場合は、breakを書かなくても問題ありません。
C#string GetMessage(int number)
{
switch (number)
{
case 1:
return "1です";
case 2:
return "2です";
default:
return "その他です";
}
}
この例では、各caseでreturnしているため、breakは不要です。
5-2. C#では原則としてフォールスルーできない
CやJavaScriptなどの言語では、breakを書かないと次のcaseに処理が流れることがあります。
これをフォールスルーと呼びます。
しかし、C#では原則として、処理のあるcaseから次のcaseへ自然に流れるフォールスルーはできません。
C#int value = 1;
switch (value)
{
case 1:
Console.WriteLine("1です");
// breakがないためエラー
case 2:
Console.WriteLine("2です");
break;
}
C#で複数のcaseに同じ処理をさせたい場合は、空のcaseを並べます。
C#int value = 2;
switch (value)
{
case 1:
case 2:
case 3:
Console.WriteLine("1から3のいずれかです");
break;
default:
Console.WriteLine("その他です");
break;
}
また、明示的に別のcaseへ移動したい場合は、goto caseを使うこともできます。
C#int value = 1;
switch (value)
{
case 1:
Console.WriteLine("1です");
goto case 2;
case 2:
Console.WriteLine("2の処理も実行します");
break;
}
ただし、goto caseはコードの流れが追いにくくなるため、使いすぎないほうがよいでしょう。
5-3. 同じcase値を重複して書けない理由
同じ値のcaseを複数書くことはできません。
C#int number = 1;
switch (number)
{
case 1:
Console.WriteLine("最初の1です");
break;
case 1:
Console.WriteLine("2つ目の1です");
break;
}
このコードはコンパイルエラーになります。
理由は、numberが1のときに、どちらのcase 1を実行すればよいか曖昧になるためです。
同じ値に対する処理は、1つのcaseにまとめましょう。
C#case 1:
Console.WriteLine("1です");
Console.WriteLine("追加の処理もここに書きます");
break;
5-4. 到達不能なcaseでコンパイルエラーになるケース
C#では、前に書いたcaseによって後ろのcaseが絶対に実行されない場合、到達不能と判断されることがあります。
特にパターンマッチングを使う場合は注意が必要です。
C#object value = "hello";
switch (value)
{
case string:
Console.WriteLine("文字列です");
break;
case "hello":
Console.WriteLine("helloです");
break;
}
この場合、"hello"は文字列なので、先にcase stringに一致してしまいます。
そのため、後ろのcase "hello"には到達できません。
正しくは、より具体的な条件を先に書きます。
C#object value = "hello";
switch (value)
{
case "hello":
Console.WriteLine("helloです");
break;
case string:
Console.WriteLine("文字列です");
break;
}
caseの順番は、単なる見た目の問題ではありません。
条件の判定結果に影響するため、具体的な条件から順番に書くことが大切です。
5-5. defaultはどこに書くべきか
defaultは、switch文の中であれば最後以外の場所にも書けます。
しかし、一般的には最後に書くのが読みやすいです。
C#switch (value)
{
case 1:
Console.WriteLine("1です");
break;
case 2:
Console.WriteLine("2です");
break;
default:
Console.WriteLine("その他です");
break;
}
defaultを最後に置くと、「どのcaseにも一致しなかった場合の処理」だと直感的に理解できます。
特別な理由がなければ、defaultは最後に書くのがおすすめです。
6. switch文を実践で使う具体例
ここからは、C#のswitch-case文を実際のプログラムで使う例を紹介します。
6-1. メニュー番号によって処理を分ける
コンソールアプリでは、メニュー番号によって処理を分ける場面があります。
C#Console.WriteLine("1: 新規作成");
Console.WriteLine("2: 保存");
Console.WriteLine("3: 終了");
Console.Write("番号を入力してください: ");
string? input = Console.ReadLine();
switch (input)
{
case "1":
Console.WriteLine("新規作成を開始します");
break;
case "2":
Console.WriteLine("保存します");
break;
case "3":
Console.WriteLine("終了します");
break;
default:
Console.WriteLine("無効な入力です");
break;
}
ユーザーが入力した値によって、実行する処理を切り替えています。
入力値は文字列として取得されるため、この例ではcase "1"のように文字列で比較しています。
6-2. 入力された文字列によって処理を分ける
コマンド入力によって処理を分ける場合にも、switch-case文は便利です。
C#Console.Write("コマンドを入力してください: ");
string? command = Console.ReadLine();
switch (command?.ToLower())
{
case "start":
Console.WriteLine("開始します");
break;
case "stop":
Console.WriteLine("停止します");
break;
case "help":
Console.WriteLine("使用できるコマンド: start, stop, help");
break;
case null:
Console.WriteLine("入力がありません");
break;
default:
Console.WriteLine("不明なコマンドです");
break;
}
ToLower()を使って小文字に変換することで、STARTやStartと入力されてもstartとして扱いやすくなります。
ただし、commandがnullになる可能性があるため、command?.ToLower()のようにnull条件演算子を使っています。
6-3. ステータスコードや状態ごとに処理を分ける
Web APIの結果や処理状態を扱うときにも、switch-case文はよく使われます。
C#int statusCode = 404;
switch (statusCode)
{
case 200:
Console.WriteLine("成功しました");
break;
case 400:
Console.WriteLine("リクエストが不正です");
break;
case 401:
Console.WriteLine("認証が必要です");
break;
case 404:
Console.WriteLine("データが見つかりません");
break;
case 500:
Console.WriteLine("サーバーエラーです");
break;
default:
Console.WriteLine("不明なステータスコードです");
break;
}
ステータスコードのように、特定の数値に意味がある場合は、switch-case文で分岐すると読みやすくなります。
ただし、コードの意味が増えてきた場合は、定数やenumを使って意味を明確にするとよいでしょう。
6-4. enumで業務ロジックの分岐を整理する
業務アプリでは、注文状態、会員種別、承認状態など、決まった種類の値を扱うことが多くあります。
そのような場合は、enumとswitch-case文の組み合わせが便利です。
C#enum PaymentStatus
{
Unpaid,
Paid,
Refunded,
Failed
}
C#PaymentStatus paymentStatus = PaymentStatus.Paid;
switch (paymentStatus)
{
case PaymentStatus.Unpaid:
Console.WriteLine("未払いです。支払いを依頼します。");
break;
case PaymentStatus.Paid:
Console.WriteLine("支払い済みです。発送準備を進めます。");
break;
case PaymentStatus.Refunded:
Console.WriteLine("返金済みです。");
break;
case PaymentStatus.Failed:
Console.WriteLine("支払いに失敗しました。再決済を案内します。");
break;
default:
Console.WriteLine("不明な支払い状態です。");
break;
}
enumを使うと、0や1のような数値だけではわからない意味を、コード上で表現できます。
結果として、条件分岐の意図が読み取りやすくなります。
7. switch式とパターンマッチングでcase文をより簡潔に書く
C#では、従来のswitch文に加えて、switch式も使えます。
switch式を使うと、値に応じて結果を返す処理を短く書けます。
7-1. switch文とswitch式の違い
switch文は、処理を実行するための構文です。
C#int number = 1;
switch (number)
{
case 1:
Console.WriteLine("One");
break;
case 2:
Console.WriteLine("Two");
break;
default:
Console.WriteLine("Other");
break;
}
一方、switch式は、値を返すための構文です。
C#int number = 1;
string message = number switch
{
1 => "One",
2 => "Two",
_ => "Other"
};
Console.WriteLine(message);
switch式では、caseやbreakを書きません。
代わりに、=>を使って「この値ならこの結果」と書きます。
7-2. switch式の基本構文
switch式の基本構文は次のとおりです。
C#var result = value switch
{
条件1 => 結果1,
条件2 => 結果2,
_ => デフォルトの結果
};
具体例を見てみましょう。
C#int day = 1;
string dayName = day switch
{
1 => "月曜日",
2 => "火曜日",
3 => "水曜日",
4 => "木曜日",
5 => "金曜日",
6 => "土曜日",
7 => "日曜日",
_ => "不明な曜日"
};
Console.WriteLine(dayName);
この例では、dayが1なので、dayNameには"月曜日"が入ります。
単純に値を変換したい場合は、従来のswitch文よりもswitch式のほうが簡潔に書けます。
7-3. パターンマッチングを使った条件分岐
C#のswitchでは、パターンマッチングを使った柔軟な条件分岐もできます。
C#object value = 123;
switch (value)
{
case int number:
Console.WriteLine($"整数です: {number}");
break;
case string text:
Console.WriteLine($"文字列です: {text}");
break;
case null:
Console.WriteLine("nullです");
break;
default:
Console.WriteLine("その他の型です");
break;
}
この例では、valueの実際の型に応じて処理を分けています。
case int numberは、valueがint型であれば一致し、その値をnumberとして使えます。
switch式でもパターンマッチングを使えます。
C#object value = "hello";
string result = value switch
{
int number => $"整数です: {number}",
string text => $"文字列です: {text}",
null => "nullです",
_ => "その他の型です"
};
Console.WriteLine(result);
型によって処理を分けたい場合や、値を取り出しながら条件分岐したい場合に便利です。
7-4. discardパターン「_」の使い方
switch式でよく使われる_は、discardパターンと呼ばれます。
これは「それ以外すべて」を表します。
C#int number = 5;
string result = number switch
{
1 => "One",
2 => "Two",
_ => "Other"
};
この例では、numberが1でも2でもない場合、_に一致します。
従来のswitch文におけるdefaultに近い役割です。
switch式では、想定外の値を受け取った場合に備えて、基本的には_を書いておくと安全です。
7-5. switch式を使うべき場面と注意点
switch式は、値を変換して返す処理に向いています。
C#string GetGrade(int score)
{
return score switch
{
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
>= 60 => "D",
_ => "E"
};
}
このように、条件に応じて1つの値を返す処理なら、switch式はとても読みやすくなります。
一方で、各条件で複数の処理を実行する場合は、従来のswitch文のほうが向いています。
C#switch (status)
{
case OrderStatus.Paid:
Console.WriteLine("支払いを確認しました");
Console.WriteLine("発送準備を開始します");
break;
}
switch式に複雑な処理を詰め込みすぎると、かえって読みにくくなります。
単純な値の変換はswitch式、複数行の処理はswitch文、というように使い分けるとよいでしょう。
8. case文とif文の使い分け
C#では、case文とif文のどちらでも条件分岐を書ける場面があります。
大切なのは、どちらを使うと読みやすいかを考えることです。
8-1. 条件が単純な値比較ならswitch-caseが読みやすい
1つの値を複数の候補と比較する場合は、switch-case文が向いています。
C#string userType = "admin";
switch (userType)
{
case "admin":
Console.WriteLine("管理者メニューを表示します");
break;
case "member":
Console.WriteLine("会員メニューを表示します");
break;
case "guest":
Console.WriteLine("ゲストメニューを表示します");
break;
default:
Console.WriteLine("通常メニューを表示します");
break;
}
このように、比較対象が同じで、候補が複数ある場合は、switch-case文のほうが構造を把握しやすくなります。
8-2. 複雑な条件式ならif文が向いている
複数の変数を組み合わせた条件や、複雑な論理式を書く場合は、if文のほうが自然です。
C#int age = 25;
bool hasLicense = true;
if (age >= 18 && hasLicense)
{
Console.WriteLine("運転できます");
}
else
{
Console.WriteLine("運転できません");
}
このような条件は、switch-case文で無理に書くよりも、if文で書いたほうがわかりやすいです。
switchでもwhenやパターンマッチングを使えば複雑な条件を書けますが、条件が込み入っている場合はif文を検討しましょう。
8-3. 可読性を下げない分岐の設計ポイント
条件分岐を書くときは、「短く書けるか」だけでなく、「読みやすいか」を重視することが大切です。
次のような場合は、switch-case文が向いています。
値の候補が明確に決まっている場合。
同じ変数を複数の値と比較する場合。
ステータス、種類、区分、コマンドなどで処理を分ける場合。
一方で、次のような場合はif文が向いています。
大小比較が中心の場合。
複数の変数を組み合わせる場合。
条件が動的に変わる場合。
複雑な条件を無理にswitchへ押し込むと、かえって読みにくくなります。
コードを読む人が自然に理解できる形を選びましょう。
9. C#のcase文をきれいに書くコツ
switch-case文は、書き方によって読みやすさが大きく変わります。
ここでは、C#のcase文をきれいに書くためのポイントを紹介します。
9-1. caseの順番を意味のある並びにする
caseの順番には意味を持たせると読みやすくなります。
たとえば、曜日なら月曜日から日曜日の順、ステータスなら処理の流れに沿った順に並べます。
C#switch (status)
{
case OrderStatus.New:
Console.WriteLine("新規注文");
break;
case OrderStatus.Paid:
Console.WriteLine("支払い済み");
break;
case OrderStatus.Shipped:
Console.WriteLine("発送済み");
break;
case OrderStatus.Canceled:
Console.WriteLine("キャンセル済み");
break;
}
関連性のない順番で並んでいると、後から読む人が理解しにくくなります。
値の意味や業務の流れに合わせて並べることを意識しましょう。
9-2. defaultで想定外の値を処理する
defaultは、想定外の値を処理するために役立ちます。
C#switch (status)
{
case OrderStatus.New:
Console.WriteLine("新規注文");
break;
case OrderStatus.Paid:
Console.WriteLine("支払い済み");
break;
default:
Console.WriteLine("想定外のステータスです");
break;
}
特に外部入力やAPIから受け取る値を扱う場合、想定していない値が来る可能性があります。
defaultでログを出したり、例外を投げたりすることで、不正な状態に気づきやすくなります。
C#default:
throw new InvalidOperationException("想定外のステータスです");
業務上ありえない値であれば、静かに無視するよりも、明確にエラーとして扱ったほうが安全な場合があります。
9-3. 長すぎるcase処理はメソッドに分ける
1つのcaseの中に長い処理を書くと、switch文全体が読みにくくなります。
C#switch (command)
{
case "create":
CreateUser();
break;
case "update":
UpdateUser();
break;
case "delete":
DeleteUser();
break;
default:
ShowError();
break;
}
このように、処理の詳細はメソッドに分けると、switch文では全体の流れだけを把握できます。
悪い例は次のようなコードです。
C#switch (command)
{
case "create":
// 入力チェック
// データ変換
// DB登録
// メール送信
// ログ出力
break;
}
caseの中が長くなってきたら、メソッドに切り出すサインです。
9-4. マジックナンバーを避けてenumや定数を使う
case 1やcase 2のような数値だけでは、その値が何を意味するのかわかりにくいことがあります。
C#switch (status)
{
case 1:
Console.WriteLine("処理中");
break;
case 2:
Console.WriteLine("完了");
break;
}
このような数値をマジックナンバーと呼びます。
読みやすくするには、enumや定数を使いましょう。
C#enum TaskStatus
{
InProgress,
Completed
}
C#switch (status)
{
case TaskStatus.InProgress:
Console.WriteLine("処理中");
break;
case TaskStatus.Completed:
Console.WriteLine("完了");
break;
}
TaskStatus.InProgressのように書くことで、値の意味がコードから読み取れるようになります。
保守性を高めるためにも、意味のある名前を使うことが大切です。
10. C#のcase文に関するよくある質問
最後に、C#のcase文についてよくある質問をまとめます。
10-1. caseに変数は使える?
通常の定数パターンとしてのcaseには、変数そのものを値として指定することはできません。
C#int target = 1;
int value = 1;
switch (value)
{
case target:
Console.WriteLine("一致しました");
break;
}
このような書き方は、意図どおりに使えない場合があります。
caseで固定値と比較したい場合は、定数を使います。
C#const int Target = 1;
int value = 1;
switch (value)
{
case Target:
Console.WriteLine("一致しました");
break;
}
変数と比較したい場合は、whenを使う方法があります。
C#int target = 1;
int value = 1;
switch (value)
{
case int x when x == target:
Console.WriteLine("一致しました");
break;
}
また、単純に変数同士を比較したいだけなら、if文のほうがわかりやすい場合もあります。
C#if (value == target)
{
Console.WriteLine("一致しました");
}
10-2. caseで比較演算子は使える?
C#の新しい構文では、リレーショナルパターンを使って比較演算子のような書き方ができます。
C#int score = 85;
switch (score)
{
case >= 80:
Console.WriteLine("合格です");
break;
default:
Console.WriteLine("不合格です");
break;
}
また、whenを使って条件を書くこともできます。
C#switch (score)
{
case int s when s >= 80:
Console.WriteLine("合格です");
break;
default:
Console.WriteLine("不合格です");
break;
}
単純な範囲条件なら、case >= 80のようなリレーショナルパターンが読みやすいです。
複雑な条件なら、whenまたはif文を使うとよいでしょう。
10-3. caseでand条件・or条件は書ける?
C#では、パターンマッチングを使ってand条件やor条件を書けます。
C#int score = 75;
switch (score)
{
case >= 60 and < 80:
Console.WriteLine("通常合格です");
break;
case >= 80 and <= 100:
Console.WriteLine("高得点合格です");
break;
default:
Console.WriteLine("不合格または不正な点数です");
break;
}
or条件は次のように書けます。
C#int day = 6;
switch (day)
{
case 6 or 7:
Console.WriteLine("休日です");
break;
default:
Console.WriteLine("平日です");
break;
}
また、従来の書き方として、複数のcaseを並べる方法もあります。
C#switch (day)
{
case 6:
case 7:
Console.WriteLine("休日です");
break;
}
単純な複数値の一致なら、どちらの書き方でも問題ありません。
10-4. defaultは必ず必要?
defaultは必須ではありません。
C#int number = 1;
switch (number)
{
case 1:
Console.WriteLine("1です");
break;
case 2:
Console.WriteLine("2です");
break;
}
このように、defaultがなくてもコードは書けます。
ただし、どのcaseにも一致しなかった場合は何も実行されません。
想定外の値を検知したい場合や、ユーザー入力を扱う場合は、defaultを書いておくのがおすすめです。
C#default:
Console.WriteLine("無効な値です");
break;
特に業務ロジックでは、不明な状態を放置するとバグに気づきにくくなります。
安全性を高めるためにも、基本的にはdefaultを用意するとよいでしょう。
10-5. switch文とswitch式はどちらを使えばいい?
複数の処理を実行したい場合は、従来のswitch文が向いています。
C#switch (command)
{
case "save":
Validate();
Save();
ShowMessage();
break;
}
一方、条件に応じて値を返すだけなら、switch式が向いています。
C#string message = status switch
{
OrderStatus.New => "新規注文です",
OrderStatus.Paid => "支払い済みです",
OrderStatus.Shipped => "発送済みです",
_ => "不明な状態です"
};
目安としては、次のように考えるとよいです。
処理を分けたいならswitch文。
値を返したいならswitch式。
複雑な条件ならif文も検討する。
どれか1つにこだわるのではなく、コードが読みやすくなる方法を選びましょう。
まとめ
C#のcase文は、switch文の中で条件ごとの処理を分けるために使います。
基本構文は、switchで判定したい値を指定し、caseで一致する値ごとの処理を書き、最後にbreakでswitch文を抜ける形です。
C#switch (value)
{
case 1:
Console.WriteLine("1です");
break;
case 2:
Console.WriteLine("2です");
break;
default:
Console.WriteLine("その他です");
break;
}
数値、文字列、enum、nullなどを扱うことができ、メニュー番号、コマンド、ステータス、業務上の状態分岐などでよく使われます。
また、C#ではcase 6 or 7のようなor条件、case >= 80のような範囲条件、whenを使った追加条件、switch式による簡潔な値の変換も可能です。
初心者が特に注意したいのは、breakの書き忘れ、フォールスルーの扱い、重複したcase、到達不能なcaseです。
C#では原則として、処理のあるcaseから次のcaseへ自然に流れるフォールスルーはできません。
そのため、各caseの最後にはbreak、return、throwなどで処理の終わりを明確にしましょう。
単純な値比較が多い場合はswitch-case文、複雑な条件式にはif文、値を返すだけならswitch式を使うと、読みやすいC#コードを書きやすくなります。

