概要
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;
}
}