多分岐処理とswitch文
if-else if-else構文は、複数の条件を順番に評価して処理を分岐させる強力な手段です。しかし、単一の変数が多数の特定の値のどれと一致するかを判定する場合、if-else ifを連鎖させるとコードが冗長になり、可読性が低下することがあります。
このような「一つの式」に基づいた多分岐処理を、よりクリーンかつ効率的に記述するために、C#にはswitch文が用意されています。
この記事では、伝統的なswitch文の構文から、C#の機能として追加された「switch式」までを解説します。
伝統的なswitch文
switch文は、括弧内の式(変数など)を評価し、その結果がcaseラベルの値と一致する場合に、そのcaseブロック内の処理を実行します。
switch文の基本構文
switch (評価する式)
{
case 値1:
// 値1 と一致した場合の処理
break; // switch文を抜ける
case 値2:
// 値2 と一致した場合の処理
break;
default:
// どの case にも一致しなかった場合の処理
break;
}
switch文の重要なルール
breakが必須: C#のswitch文では、各caseブロックの最後にbreak;(またはreturnなど、処理を抜けるステートメント)を記述することが原則として必須です。breakを書き忘れるとコンパイルエラーになります(意図的なフォールスルーは例外的な書き方でのみ可能です)。defaultブロック:defaultブロックはオプションですが、どのcaseにも一致しなかった場合の処理を定義するために使用されます。if-else構文の最後のelseに相当します。
コード例:HTTPステータスコードの判定
int型のHTTPステータスコードに応じて、異なるメッセージをコンソールに出力する例です。
using System;
public class SwitchStatementExample
{
public static void Main()
{
int httpStatusCode = 404;
string statusMessage = "";
// 伝統的な switch 文
switch (httpStatusCode)
{
case 200:
statusMessage = "OK: 成功しました。";
break;
case 400:
statusMessage = "Bad Request: リクエストが無効です。";
break;
case 404:
statusMessage = "Not Found: リソースが見つかりません。";
break;
case 500:
statusMessage = "Internal Server Error: サーバー内部エラー。";
break;
default:
statusMessage = $"Unknown: 不明なステータスコード ({httpStatusCode}) です。";
break;
}
Console.WriteLine(statusMessage);
}
}
出力結果:
Not Found: リソースが見つかりません。
C# 7.0以降の switch文(パターンマッチング)
C# 7.0以降、switch文は機能強化され、単なる定数値との比較(case 404:)だけでなく、when句を使った追加の条件(パターンマッチング)も指定できるようになりました。
when句の使用例
caseで大まかな型や値を指定し、whenで詳細な条件を指定できます。
using System;
public class SwitchWhenExample
{
public static void Main()
{
// 400番台だが 404 ではないコード
int httpStatusCode = 403;
string statusCategory = "";
switch (httpStatusCode)
{
case 200:
statusCategory = "Success (成功)";
break;
// 404 は個別に処理
case 404:
statusCategory = "Not Found (特例)";
break;
// 400番台(400~499)のクライアントエラー
// 404 は上で処理済み
case int code when (code >= 400 && code < 500):
statusCategory = "Client Error (クライアントエラー)";
break;
// 500番台(500~599)のサーバーエラー
case int code when (code >= 500 && code < 600):
statusCategory = "Server Error (サーバーエラー)";
break;
default:
statusCategory = "Other";
break;
}
Console.WriteLine($"コード: {httpStatusCode}, 分類: {statusCategory}");
}
}
出力結果:
コード: 403, 分類: Client Error (クライアントエラー)
C# 8.0以降の switch式(Switch Expressions)
C# 8.0では、switchの機能が「式(Expression)」として使用できるようになりました。switch文が「処理を実行する」ものであったのに対し、switch式は「値を返す」ものです。
これにより、先ほどのHTTPステータスコードの例は、はるかに簡潔に記述できます。
switch式の構文
var 変数 = 評価する式 switch
{
パターン1 => 返す値1,
パターン2 => 返す値2,
_ => デフォルトで返す値 // default の代わり
};
switch式のコード例
switch式は、C# 9.0で導入された関係パターン(>=, <など)と組み合わせることで、非常に強力になります。
using System;
public class SwitchExpressionExample
{
public static void Main()
{
int httpStatusCode = 503;
// switch 式 を使って値を直接 statusCategory 変数に代入する
string statusCategory = httpStatusCode switch
{
// C# 9.0 (関係パターン)
200 or 201 => "Success",
>= 300 and < 400 => "Redirection",
404 => "Not Found",
>= 400 and < 500 => "Other Client Error",
>= 500 => "Server Error",
// _ は default に相当 (どのパターンにも一致しない場合)
_ => "Unknown"
};
Console.WriteLine($"コード: {httpStatusCode}, 分類: {statusCategory}");
}
}
出力結果:
コード: 503, 分類: Server Error
このswitch式は、breakが不要であり、各パターンが=>(アロー)を使って値を直接返すため、非常に直感的で簡潔なコードになります。
まとめ
switchは、単一の変数に基づく多分岐処理を実装するのに適しています。
- 伝統的な
switch文:caseとbreakを使用する基本的な構文です。 when句: C# 7.0以降、caseに詳細な条件を追加できます。switch式: C# 8.0以降、switchを「値を返す式」として使用でき、C# 9.0の関係パターンと組み合わせることで、if-else ifよりもはるかに簡潔に範囲判定などを記述できます。
用途に応じてこれらの構文を使い分けることで、C#のコードの可読性と保守性を高めることができます。
