switch式の書き方 チートシート

もくじ

目次(WPF/xaml/C#/C++関連メモ) - tera1707’s blog

やりたいこと

C#の8.0で、switch式という書き方ができるようになったらしい。 実験的に試してみたら、なるほどーとはなるが、実際どういうときに使えるのかがあまりよくわかってなく、ぱっと書き方が出てこないので、こういう書き方ができる、というのをざっと並べておきたい。

switch式の書き方いろいろ

普通のswitch式

「その他」を書くときに"_"を使う場合。

    var val = 1;

    var y = val switch
    {
        1 => "1です",
        2 => "2です",
        _ => "変な値です",
    };

普通のswitch式

「その他」を書くときに"var"を使う場合。

    var val = 1;

    var y = val switch
    {
        1 => "1です",
        2 => "2です",
        var v => v + "は変な値です",
    };

タプルのswitch式

一気に複数の値を見れるswitch、のイメージ。 タプルの中に"_"を書くと、その値は「なんでもいい」になる。

    var val = (1, 2);

    var y = val switch
    {
        (10, 20) => "1です",
        (1, _) => "(1, _)です",
        _ => "変な値です",
    };

または

    var val1 = 1;
    var val2 = 2;

    var y = (val1, val2) switch
    {
        (1, 2) => "1です",
        (1, _) => "(1, _)です",
        _ => "変な値です",
    };

switch式+when

判定する値そのものに対して、複数条件を指定できそう。 値が「0から10の間か?」の判定(0 < a && a < 10)とか。

    var val = 5;

    var y = val switch
    {
        var a when (0 < a && a <= 10) => a + "は0~10の値です",
        var a when (10 < a && a <= 20) => a + "は10~20の値です",
        _ => "変な値です",
    };

ほぼ同じことが下記でもできる。リレーショナルパターンというらしい。 (whenを使ったときとの違いは、式(=>の後ろ)の中で、判定した値を使えるか使えないか、位か...)

    var val = 15;

    var y = val switch
    {
        < 10 => "~10の値です",
        >= 10 and < 20=> "10~20の値です",
        _ => "20より大です",
    };

または、判定する値がclass等の時に、そのメンバを使って複数の条件を指定できそう。

    Process[] proc = Process.GetProcesses();

    var y = proc switch
    {
        var p when p.Any(x => x.ProcessName == "notepad") => "メモ帳起動してます",
        var p when p.Any(x => x.ProcessName == "devenv") => "VisualStudio起動してます",
        _ => "めぼしい奴は起動してません",
    };

型の判定

switchにかけるものの型を判定し、それを使った式を書ける。

    object val = "abc";

    var y = val switch
    {
        int i => i + "です",
        string str => str + "です",
        var v => v + "は変な値です",
    };

※クラスが一致するかや、インターフェースを実装しているか、もチェックできる。

型の判定したうえで条件判定する

型の判定したうえでwhenを使う。

    object val = 2;

    var y = val switch
    {
        int i when (i == 2) => "2です",
        string str when (str == "bbb") => "1です",
        var v => v + "は変な値です",
    };

switchにかけるオブジェクトのプロパティの判定をする

    Process? proc = Process.GetProcessesByName("notepad").FirstOrDefault();

    var y = proc switch
    {
        Process { ProcessName: "notepad" } => 1,
        Process { ProcessName: "devenv" } => 2,
        _ => 3,
    };

switch式の中のProcess は省略できる。下記のようにも書ける。

    Process? proc = Process.GetProcessesByName("notepad").FirstOrDefault();

    var y = proc switch
    {
        { ProcessName: "notepad" } => 1,
        { ProcessName: "devenv" } => 2,
        _ => 3,
    };

一旦、一時変数にプロパティの名前を入れて、それをwhenで条件として使える。

Process? proc = Process.GetProcessesByName("notepad").FirstOrDefault();

var y = proc switch
{
    { ProcessName: var name } when name == "notepad" => 1,
    { ProcessName: var name } when name == "devenv" => 2,
    _ => 3,
};

switchにかけるオブジェクトのプロパティの判定をしてさらに条件をつける

    var y = Process.GetProcessesByName("notepad").FirstOrDefault() switch
    {
        Process { ProcessName: "notepad" } p when p.Id > 1 => 1,
        Process { ProcessName: "devenv" } p when p.Id > 1 => 2,
        _ => 3,
    };

ここに、全部のパターンが書いてある!

下の「参考」にも入れたが、ここにswitch式に使えるパターンが全部書いてある。

docs.microsoft.com

参考

switch式

ufcpp.net

switch式は「パターンマッチング」の一部。

ufcpp.net

MS公式、switch式

docs.microsoft.com

MS公式、パターン

docs.microsoft.com

タプルの「分解」

ufcpp.net