LoginSignup
16
12

C# SWITCHの進化

Last updated at Posted at 2022-04-28

概要

C#のバージョンアップでSwitchにいろいろな使い方が増えたから、メモとして使い方を纏めてみました。
文書で説明するのが大変だから、文書少なめでプログラムがメインに記述しました。

今までのSwitch

C# 6.0以前 switchのcaseラベルでは定数式のみ使用できます

従来の使い方
int i = 0;
switch(i){
 case 10:
   Console.WriteLine("10");
   break;
 case 20:
   Console.WriteLine("20");
   break;
 case 30:
   Console.WriteLine("30");
   break;
 case 40:
   Console.WriteLine("40");
   break;
 default:
   Console.WriteLine("other");
   break;
}
//こんな感じでcaseラベルでは定数式のみ使用できます、
//そしてcaseラベルの定数式のの型は「char,string,bool,int,double,enum」等の組込み型だけ使用できます。

バージョンアップ

だが以下のバージョンアップによって、今のswitchはいろんな使い方が増えました。

  • C# 7.0 パターンマッチング機能の追加
  • C# 8.0 switch式の導入
  • C# 9.0 パターンマッチング機能の増強

新しいSwitchの使い方纏め

Switchステートメント
object objSwitch= 1l;
switch (objSwitch)
{
    //定数パターン
    case 10:
        Console.WriteLine("is 10");
        break;
    //定数と論理(or)パターン
    case 30 or 40 or 50:
        Console.WriteLine("is 30 or 40 or 50");
        break;
    //リレーションと論理(and)パターン
    case > 10 and < 20:
        Console.WriteLine("is > 10 and < 20");
        break;
    //型と論理(or)パターン
    case int or long:
        Console.WriteLine("is int or long");
        break;
    //型パターン
    case double:
        Console.WriteLine("is double");
        break;
    //型パターン
    case string:
        Console.WriteLine("is string");
        break;
    //「10」がintになる、case intで処理されるからここに記述するとエラーになる
    //case 10:
    //    Console.WriteLine("is 10");
    //    break;
    //破棄パターン
    // 「var _」が「default」似ている、
    // だが「var _」と「default」の前後順と関係なく「var _」が優先されるから、「default」が処理されなくなる
    case var _:
        Console.WriteLine("is other");
        break;
    // 但しswitchステートメントでは「default」を利用する方がより安全
    //default:
    //    Console.WriteLine("is other");
    //    break;
}

C# 8.0からswitch式が追加されたので、上記のswitchステートメントをswitch式に書き換えると

Switch式
//メソッドの戻り値が必須、switch式では何なかの値を帰す必要があります
public static string SwitchTest(object objSwitch) => objSwitch switch
{
    10 => "is 10",
    30 or 40 or 50 => "is 30 or 40 or 50",
    > 10 and < 20 => "is > 10 and < 20",
    int or long => "is int or long",
    double => "is double",
    string => "is string",
    _ => "is other"
};

SwitchプロパティパターンではSwitchのCaseの判断式に直接パラメータのプロパティやフィールドを利用できるようになりました。

Switchプロパティパターン
public class People
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string City { get; set; }
    public string Gender { get; set; }
    public string Tel { get; set; }
    public DateTime Birthday { get; set; }
}

//Switch式
public static string SwitchPeopleBlock(People people) => people switch
{
    { City:"東京",Age:30} => "A-1 block",
    { City: "東京", Age: 25 } => "A-2 block",
    { City: "東京", Age: >30 and < 40 } => "A-3 block",
    { City: "大阪", Age: 30 } => "B-1 block",
    { City: "大阪", Age: 25 } => "B-2 block",
    { City: "大阪", Age: > 30 and < 40 } => "B-3 block",
    { City: "東京", Age: 55 } or { City: "大阪", Age: 55 } => "C-1 block",
    _ => "NO block",
};


static void Main(string[] args)
{
	var p = new People { City = "東京", Age = 55 };
	Console.WriteLine(SwitchPeopleBlock(p));

    //Switchステートメント
	switch (p)
	{
	    case { City: "東京", Age: 30 }:
	        Console.WriteLine("A-1 block");
	        break;
	    case { City: "東京", Age: 25 }:
	        Console.WriteLine("A-2 block");
	        break;
	    case { City: "東京", Age: > 30 and < 40 }:
	        Console.WriteLine("A-3 block");
	        break;
	    case { City: "大阪", Age: 30 }:
	        Console.WriteLine("B-1 block");
	        break;
	    case { City: "大阪", Age: 25 }:
	        Console.WriteLine("B-2 block");
	        break;
	    case { City: "大阪", Age: > 30 and < 40 }:
	        Console.WriteLine("B-3 block");
	        break;
	    case { City: "東京", Age: 55 } or { City: "大阪", Age: 55 }:
	        Console.WriteLine("C-1 block");
	        break;
	    case var _:
	        Console.WriteLine("NO block");
	        break;
	}
}

Switchでタプル型の式も簡単処理できます

Switch位置指定パターン(タプル型)
public class People
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string City { get; set; }
    public string Gender { get; set; }
    public string Tel { get; set; }
    public DateTime Birthday { get; set; }
}

//Switch式
public static string SwitchPeopleBlock(string City, int Age) => (City, Age) switch
{
    ("東京", 30 ) => "A-1 block",
    ("東京", 25 ) => "A-2 block",
    ("東京", > 30 and < 40 ) => "A-3 block",
    ("大阪", 30 ) => "B-1 block",
    ("大阪", 25 ) => "B-2 block",
    ("大阪", > 30 and < 40 ) => "B-3 block",
    ("東京", 55 ) or ( "大阪", 55 ) => "C-1 block",
    var (x, y) when y > 70 => "D-1 block",// varで使ってパラメータを一旦変数に保存してから計算することも可能
    //var (_, y) when y > 70 => "D-1 block",// 「_」で利用しない変数の不必要な代入を省ける
    _ => "NO block",
};


static void Main(string[] args)
{
	Console.WriteLine(SwitchPeopleBlock("東京", 30));
    Console.WriteLine(SwitchPeopleBlock("東京", 80));

    //Switchステートメント
    switch ("東京", 30)
	{
	    case ("東京", 30):
	        Console.WriteLine("A-1 block");
	        break;
	    case ("東京", 25):
	        Console.WriteLine("A-2 block");
	        break;
	    case ("東京", > 30 and < 40):
	        Console.WriteLine("A-3 block");
	        break;
	    case ("大阪", 30):
	        Console.WriteLine("B-1 block");
	        break;
	    case ("大阪", 25):
	        Console.WriteLine("B-2 block");
	        break;
	    case ("大阪", > 30 and < 40):
	        Console.WriteLine("B-3 block");
	        break;
	    case ("東京", 55) or ("大阪", 55):
	        Console.WriteLine("C-1 block");
	        break;
        // varで使ってパラメータを一旦変数に保存してから計算することも可能
        case var (x, y) when y > 70:
        //case var (_, y) when y > 70: 「_」で利用しない変数の不必要な代入を省ける
            Console.WriteLine("D-1 block");
            break;
	    case var _:
	        Console.WriteLine("NO block");
	        break;
	}
}

16
12
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
12