C# switch式でのパターンマッチング

C#

C# 8.0 以降、switch式でパターンマッチングを利用できるようになりました。

定数パターン

リテラルや const 変数にマッチします。

C#
x switch
{
  0        => "ゼロ",
  1        => "イチ",
  _        => "それ以外"
};

string day = "Sunday";
string type = day switch
{
    "Saturday" => "週末",
    "Sunday"   => "週末",
    "Monday"   => "平日",
    "Tuesday"  => "平日",
    "Wednesday"=> "平日",
    "Thursday" => "平日",
    "Friday"   => "平日",
    _          => "不明"
};

const int Admin = 0;
const int User = 1;
const int Guest = 2;

int role = 1;
string label = role switch
{
    Admin => "管理者",
    User  => "一般ユーザー",
    Guest => "ゲスト",
    _     => "不明なロール"
};

型パターン

オブジェクトが特定の型を持つかを判定し、かつ変数宣言できます。

C#
object value = 42;

string result = value switch
{
    int i    => $"整数: {i}",
    string s => $"文字列: \"{s}\"",
    bool b   => $"真偽値: {b}",
    _        => "その他の型"
};

object input = "Hello World";

string message = input switch
{
    string s when s.Length > 10 => "長めの文字列",
    string s                    => $"短めの文字列({s.Length}文字)",
    int i when i > 1000         => "4桁以上の整数",
    int                         => "小さめの整数",
    _                           => "その他"
};

object? data = null;

string status = data switch
{
    null       => "null値です",
    string s   => $"文字列({s})",
    int i      => $"整数({i})",
    _          => "その他"
};

プロパティパターン

オブジェクトのプロパティの値に基づいてパターンマッチングを行うことができます。

C#
record Person(string Name, int Age);

Person p = new("Alice", 20);
string category = p switch
{
  { Age: < 13 }   => "子ども",
  { Age: < 20 }   => "ティーン",
  { Age: >= 20 }  => "大人",
  _               => "不明"
};

プロパティに直接マッチします。以下のようにフィルタを付加することもできます。

C#
record Person(string Name, int Age);

Person person = new("Asnr", 23);

string category = person switch
{
    { Age: var age } when age < 13   => "子ども",
    { Age: var age } when age < 20   => "ティーン",
    { Age: var age } when age < 65   => "大人",
    _                                => "シニア"
};

位置指定パターン

C#9以降で使えます。Deconstruct メソッドと連携し、タプルのようにマッチします。
Deconstructについては別項参照(C# の Deconstruct

C#
record Point(int X, int Y);

var pt = new Point(0, 0);
string pos = pt switch
{
  (0, 0)      => "原点",
  (0, _)      => "Y 軸上",
  (_, 0)      => "X 軸上",
  _           => "その他"
};

タプルパターン

タプルの2つ以上の値を同時にマッチすることができます。

C#
(int x, int y) = (3, -1);
string quo = (x, y) switch
{
  ( > 0, > 0) => "第1象限",
  ( < 0, > 0) => "第2象限",
  ( < 0, < 0) => "第3象限",
  ( > 0, < 0) => "第4象限",
  _           => "軸上"
};

タプルパターンにさらに条件分岐をつけます。

C#
(int a, int b) = (5, 10);

string relation = (a, b) switch
{
    var (x, y) when x == y        => "等しい",
    var (x, y) when x > y         => "a は b より大きい",
    var (x, y) when x < y         => "a は b より小さい",
    _                             => "不明"
};

コメント

タイトルとURLをコピーしました