[C#] switch文をswitch式で表現する

C#

はじめに

今回は、今まで利用していたswitch文をより効率的に、コード数も極力少なくしたswitch式の書き方についての備忘録です。

今までのswitch文は下記のような感じでした。

public static void Main(string[] args)
{
   //string target = Console.ReadLine();
   string target = Console.ReadLine();
   switch(target) {
       case "1":
           Console.WriteLine("target value is 1");
           break;
       case "2":
            Console.WriteLine("target value is 2");
            break;
        default:
            break;
    }
}

上記だと、毎回breakやcaseなどを一つ一つ書く必要がありました。

C# 8.0からはこのswitch文をとても簡略化して書くことができるようになります。

switch式の利用方法

では早速switch式で書いてみたいと思います。

var target2 = target switch{
     "1" => "target value is 1",
     "2" => "target value is 2",
      _ => throw new InvalidOperationException()
};
Console.WriteLine(target2);

「_(アンダーバー」はその上にある条件にマッチしない場合に設定するもので、「default:」と同じ意味を持ちます。

Null許容型に対するnullチェック

Null許容型に対して、設定した値が入っているかどうかの条件と設定した以外の値が入っているかどうかの条件、nullだった場合の条件に対して下記のような書き方ができます。

int? target = null;

var target2 = target switch{
     "1" => "target value is 1",
     "2" => "target value is 2",
     { } => "target value is not null", 
      _ => throw new InvalidOperationException()
};

Console.WriteLine(target2);

{ } 部分が設定した値以外の値が入っていた場合の条件を表しています。

上記はtarget変数に「null」を指定しているので、実行した結果「InvalidOperationException」が出力されます。代わりに「3」など条件設定されていない変数を代入した場合は、「target value is not null」となります。

配列に対するswitch式

では配列に対して、ある値が入っていた場合のswitch式の例となります。

string[] targetArr = new string[] { "test1", "test2" };
var target2 = (targetArr[0], targetArr[1]) switch{
      ("test1", "test2") => "target value is test1 and test2",
      _ => throw new InvalidOperationException()
};

Console.WriteLine(target2);

foreach(string t in targetArr) 
{
    var target3 = t switch {
       "test1" => "target value is test1",
       _ => throw new InvalidOperationException()
    };
    Console.WriteLine(target3);
}

前者は、タプル型の考え方で、一つの変数に複数の値を格納してswitch式に当てはめています。

後者の方は、foreachで回してマッチしたものを出力するイメージです。

プロパティ値に対するswitch式

指定したクラスのプロパティ値に対しても同様にswitch式の利用が可能です。

public class SampleProperty 
{
    public string Sample1 { get; set;}
    public bool Sample2 {get; set;}
}

public static void Main(string[] args)
{
    SampleProperty sp = new SampleProperty();
    sp.Sample1 = "test1";
    sp.Sample2 = false;

    string msg = sp switch{
         {Sample2: false} => "false is set",
          _ => "true is set"
     };
     Console.WriteLine(msg);

     msg = sp switch {
         {Sample1: "test1", Sample2: false} => "test1 and false is set",
         _ => "invalid"
    };
    Console.WriteLine(msg);
}

前者はあるプロパティ値に対しての判定処理であり、後者の方は複数のプロパティ値に対して判定しています。

switch式では複数のプロパティ値に対しても比較することができるので便利です。

Whenを利用した追加条件

追加で条件を指定したい場合には「When」を利用することができます。

public static void Main(string[] args)
{
    var num = 120;
    string msg = num switch
    {
        int i when i > 100 => $"値は100より大きいint型のです {num}",
        _ => "invalid"
    };

    Console.WriteLine(msg);
}

上記例では、対象変数がint型でありかつその値が100より大きい場合の条件判定となります。

最後に

段々と便利になってきているC#ですが、昔からプログラミングをやっている方にとっては少し苦戦するかもしれません。

ただ、とても便利な書き方なので、是非お試しください。

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