C# 7.0 以降、switch 文の機能が大幅に拡張され、「パターンマッチング」が利用可能になりました。これにより、単なる定数の一致判定だけでなく、型の判定や、when 句を用いた詳細な条件判定が可能になっています。
従来は if-else 文を連ねて記述していたような複雑な条件分岐も、switch 文を使うことで構造化され、可読性の高いコードに書き換えることができます。
本記事では、object 型の入力を受け取り、その型と値の条件(範囲など)に基づいて処理を振り分ける実装例を紹介します。
実装例:型と値の複合条件判定
以下のコードは、様々な型のデータが混在するリストを処理するシミュレーションです。switch 文の中で case 型 変数 when 条件式 という構文を使用し、型チェックと値の評価を同時に行っています。
using System;
namespace SwitchPatternExample
{
class Program
{
static void Main(string[] args)
{
// 処理対象のデータ(int, double, string, nullなどが混在)
object[] rawData = { 100, -5, 3.14, 0.01f, "Status OK", null };
Console.WriteLine("--- データ解析開始 ---");
foreach (var data in rawData)
{
ProcessData(data);
}
}
static void ProcessData(object data)
{
switch (data)
{
// 1. 型パターン + when句(ガード条件)
// int型であり、かつ 1 以上の場合
case int i when i >= 1:
Console.WriteLine($"[正の整数] 値: {i}");
break;
// 2. 同じint型でも条件が異なる場合
// 上記の条件(>= 1)にマッチしなかったint型がここに来る
case int i:
Console.WriteLine($"[その他の整数] 値: {i}");
break;
// 3. 複数のケースラベルのフォールスルー
// double型 または float型 で、かつ 1.0 以上の場合
// 異なる型であってもロジックを共有できる
case double d when d >= 1.0:
case float f when f >= 1.0f:
Console.WriteLine($"[1.0以上の実数] 値: {data}");
break;
// 4. 特定の値を持つ文字列の場合(定数パターン)
case "Status OK":
Console.WriteLine("[ステータス] 正常です。");
break;
// 5. nullチェック
case null:
Console.WriteLine("[エラー] データが null です。");
break;
// 6. どの条件にも一致しない場合
default:
Console.WriteLine($"[未対応の型] {data.GetType().Name}");
break;
}
}
}
}
解説とポイント
1. 型パターンと変数宣言
case int i のように記述することで、変数 data が int 型であるかを判定し、安全にキャストした結果を変数 i に代入します。この変数 i は、その case ブロック内でのみ有効です。
2. when句(ガード条件)
case ... when 条件式 と記述することで、型の一致に加えて、さらに細かい条件(値の範囲など)を追加できます。これを「ガード条件」と呼びます。
C#
case int i when i >= 1:
この機能により、データ型に応じたバリデーションロジックを switch 文の中にスッキリと収めることができます。
3. 評価の順序
switch 文は上から順に評価されます。そのため、より厳しい条件(範囲が狭い条件)を上に、緩い条件(包括的な条件)を下に記述する必要があります。 例えば、上記のコードで case int i: を case int i when i >= 1: よりも先に記述してしまうと、すべての整数が最初のケースに吸い込まれてしまうため、意図した動作になりません。
まとめ
when 句を併用したパターンマッチングを利用することで、C# の switch 文は非常に強力な制御構造となります。
- 型安全: キャストの手間が省ける。
- 柔軟性: 値の範囲やプロパティの状態など、任意の条件を付与できる。
- 可読性: 複雑な
if (obj is int i && i >= 1) ...のような記述を整理できる。
多様な入力パターンがあり得るデータ処理や、ステートマシンの実装などで積極的に活用してください。
