C#のswitch
文は、複数の条件分岐を読みやすく整理できる構文です。
特に、同じ変数の値に応じて処理を切り替える場面で力を発揮します。
if-elseが増えて見通しが悪くなったら、switch
でスッキリ書けないかを検討するのが上達の近道です。
この記事では基本からサンプルコードまで、初心者向けに丁寧に解説します。
C#のswitch文とは?
if-elseとの違いと使い分け(初心者向け)
同じ変数の値に応じて分岐させる場合、switch
は構造がはっきりしていて読みやすくなります。
例えば、数値の1〜5、それぞれに異なるメッセージを表示したいときに向いています。
if-else
は条件が複雑で比較演算や範囲判定を多用する場面、switch
は離散的な値ごとの分岐に向いている、という使い分けが基本です。
初学者のうちは、条件が「Aならこれ、Bならこれ、その他はこれ」という形ならswitch
を優先するとよいでしょう。
以下に、両者の使い分けを簡単に整理します。
観点 | if-else | switch | 向いているケース |
---|---|---|---|
可読性 | 条件が増えると読みにくい | 値ごとの分岐を整然と書ける | 値が列挙できる場合 |
条件の種類 | 複雑な論理式や範囲判定が得意 | 等価比較が中心 | 列挙型や定数比較 |
メンテナンス | 条件追加でネスト化しがち | case追加で拡張しやすい | 分岐の追加や整理 |
迷ったら「同じ値の比較が並ぶか」を基準に選ぶと判断しやすくなります。
複数条件をスッキリ書くポイント
switch
は「同一の評価対象」について「複数の具体的な候補」を列挙するのに最適です。
ケースをまとめたり、default
で漏れを防いだりすることで、分岐の全体像を短く保てます。
C# 7以降では複数のcase
ラベルを並べる書き方、C# 9以降ではor
パターンも使えるため、重複コードを避けやすくなりました。
先に入力の正規化(例: 文字列をToLowerInvariant()
で小文字に統一)をしておくと、caseの数を減らせます。
C# switch文の基本構文
switchの書き方(基本構文)
まずは形を押さえましょう。
ここでは雰囲気をつかむためのひな型を示します。
// 基本構文(イメージ)
// switch (評価したい式) に対し、case 値: ごとの処理を書き、最後に break; で抜けます。
switch (式)
{
case 値1:
// 値1に一致したときの処理
break; // 忘れると他のcaseへ落ちるのを防げます(C#では落下は原則エラー)
case 値2:
// 値2に一致したときの処理
break;
default:
// どのcaseにも一致しなかったときの処理
break;
}
ひとつのswitch
につき、評価する対象は1つで、判定は上から順に行われます。
caseとbreakの役割
case
は一致条件のラベル、break
はその分岐の処理を終えてswitch
全体から抜ける命令です。
C#では、非空のcase
から次のcase
へ「落ちる」ことは許可されず、break
やreturn
などの終了文が必要です。
複数のcase
を同じ処理にまとめたい場合は、ラベルを続けて書くか、C# 9以降のor
パターンを使います。
defaultの使い方
default
は、どのcase
にも一致しなかったときの保険です。
将来の値追加や予期しない入力に備えて、default
でログや注意メッセージを出すとデバッグ性が上がります。
「絶対に全列挙している」と思っても、default
を入れておくと安心です。
C# switch文のサンプルコード
数値(int)でのswitch
整数の値に応じて難易度名を表示する例です。
using System;
class Program
{
static void Main()
{
// 難易度を表す数値(1〜3)を例として用意
int level = 2;
switch (level)
{
case 1:
Console.WriteLine("難易度: かんたん");
break;
case 2:
Console.WriteLine("難易度: ふつう");
break;
case 3:
Console.WriteLine("難易度: むずかしい");
break;
default:
// 想定外の数値に備える
Console.WriteLine("不明な難易度です");
break;
}
}
}
難易度: ふつう
同じ変数level
の値ごとに処理がまとまり、読みやすくなっています。
文字列(string)でのswitch
コマンド文字列を判定します。
文字列比較は大文字小文字を区別するため、先に小文字へ揃えています。
using System;
class Program
{
static void Main()
{
// 例としてコマンドを用意(実運用ではユーザー入力を想定)
string command = "Start";
// 大文字小文字の違いによるミスを防ぐために小文字へ正規化
string normalized = command.ToLowerInvariant();
switch (normalized)
{
case "start":
Console.WriteLine("処理を開始します");
break;
case "stop":
Console.WriteLine("処理を停止します");
break;
case "status":
Console.WriteLine("状態を表示します");
break;
default:
Console.WriteLine("未知のコマンドです");
break;
}
}
}
処理を開始します
正規化せずに"Start"
(1文字目が大文字になっている)でcase "start"
と比べると一致しません。
列挙型(enum)でのswitch
列挙型はswitch
と相性がよく、値が限定されるため安全です。
using System;
enum OrderStatus
{
Pending, // 受付
Processing, // 処理中
Shipped, // 出荷済み
Canceled // キャンセル
}
class Program
{
static void Main()
{
OrderStatus status = OrderStatus.Processing;
switch (status)
{
case OrderStatus.Pending:
Console.WriteLine("ご注文を受け付けました");
break;
case OrderStatus.Processing:
Console.WriteLine("ご注文を処理中です");
break;
case OrderStatus.Shipped:
Console.WriteLine("ご注文を出荷しました");
break;
case OrderStatus.Canceled:
Console.WriteLine("ご注文はキャンセルされました");
break;
default:
// enumに将来値が追加されても検知できるように
Console.WriteLine("不明なステータスです");
break;
}
}
}
ご注文を処理中です
enumとswitch
を組み合わせると、意図しない値を避けつつ分岐を列挙でき、保守性が高まります。
複数のcaseをまとめる書き方
同じ処理にしたいケースをまとめる2つの方法です。
using System;
class Program
{
static void Main()
{
int month = 1;
// 方法1: caseラベルを連続して同じブロックにまとめる(古くからある書き方)
switch (month)
{
case 12:
case 1:
case 2:
Console.WriteLine("冬");
break;
case 3:
case 4:
case 5:
Console.WriteLine("春");
break;
default:
Console.WriteLine("その他の季節");
break;
}
// 方法2: C# 9以降なら or パターンで簡潔に書けます
switch (month)
{
case 12 or 1 or 2:
Console.WriteLine("冬");
break;
case 3 or 4 or 5:
Console.WriteLine("春");
break;
default:
Console.WriteLine("その他の季節");
break;
}
}
}
冬
冬
ラベルの連続またはor
パターンを使うと、重複コードを避けて意図を明確にできます。
ユーザー入力を判定する簡単な例
ユーザーの年齢入力に応じて料金区分を表示する例です。
入力検証も最小限入れています。
using System;
class Program
{
static void Main()
{
Console.Write("年齢を入力してください: ");
string? input = Console.ReadLine();
// 数値に変換できるか試みる
if (!int.TryParse(input, out int age) || age < 0)
{
Console.WriteLine("年齢は0以上の整数で入力してください");
return; // switchに入らず終了
}
// 年齢から区分コードを決める(0: 幼児, 1: 子ども, 2: 大人, 3: シニア)
int categoryCode =
age < 6 ? 0 :
age < 13 ? 1 :
age < 65 ? 2 : 3;
// switchで表示メッセージを分岐
switch (categoryCode)
{
case 0:
Console.WriteLine("区分: 幼児(無料)");
break;
case 1:
Console.WriteLine("区分: 子ども(半額)");
break;
case 2:
Console.WriteLine("区分: 大人(通常料金)");
break;
case 3:
Console.WriteLine("区分: シニア(割引)");
break;
default:
// ロジックの不整合を検知
Console.WriteLine("区分を判定できませんでした");
break;
}
}
}
出力例(入力が25の場合):
年齢を入力してください: 25
区分: 大人(通常料金)
事前に数値変換や範囲チェックを済ませ、switch
では「表示ロジック」のみに集中させると可読性が上がります。
switch文の注意点とコツ
breakの入れ忘れに注意
C#ではcase
内から次のcase
へ暗黙に落ちることはできません。
そのためbreak
やreturn
、throw
などの終了文が必要です。
入れ忘れるとコンパイルエラーになるため、問題箇所を早期に発見できます。
複数case
をまとめたいときはラベル連続やor
パターンを使いましょう。
同じcase値は重複不可
同じ値を指すcase
は重複定義できません。
例えばcase 1:
を2回書くとコンパイルエラーになります。
重複しそうな場合は、まとめ方(ラベル連続やor
パターン)に置き換えてください。
文字列は大文字小文字を区別
文字列のswitch
は既定で大文字小文字を区別します。
ユーザー入力など揺れがあるデータは、ToLowerInvariant()
やToUpperInvariant()
で正規化してからswitch
に渡すのが安全です。
あるいはcase "start": case "Start":
のようにラベルを並べる方法もありますが、ラベル増加で保守性が下がりやすい点に注意しましょう。
分岐は短く保つ(可読性重視)
switch
の各ブロックは「1つの責務」に絞り、長い処理はメソッドに分けるのが定石です。
分岐が多くなり過ぎる場合は、データ駆動(例えば辞書Dictionary
で値から関数を引く)や、C#のswitch式への置き換えも検討してください。
これにより、意図を短く明確に表現できます。
まとめ
本記事では、C#のswitch
文の基本と使い所、そして数値・文字列・列挙型のサンプルを通して実践的な書き方を解説しました。
「同じ対象の値に応じて処理を切り替える」場面ではswitch
を選ぶと、可読性と保守性が大きく向上します。
また、default
で漏れを防ぎ、break
や入力正規化を徹底することで、初心者でも堅牢な分岐を書けます。
まずは小さなプログラムで手を動かし、caseのまとめ方やenumとの相性などのコツを体感してみてください。