tags:[C#]
C# 8.0から使用できるSwitvh 式(Switch Expression)
Switch文(Switch Statement)とは明確に違っていてステートによるではなくパターンマッチングにを行う
正直、この辺読んでおけばこの記事を読む必要はない
- switch 式 - 'switch' 式を使ってパターン マッチ式を評価します | Microsoft Learn
- C# 8.0 switch 式 | ++C++; // 未確認飛行 C ブログ (ufcpp.net)
Switch文からの置き換え
やりたいことはどちらもある条件を評価して条件分岐なので おきかえることができる 以下のようなSwitch文は
public static void SwitchStatment(TestEnum e) { string consoleText; switch (e) { case TestEnum.Test1: consoleText = "Swirch Test1"; break; case TestEnum.Test2: consoleText = "Swirch Test2"; break; case TestEnum.Test3: consoleText = "Swirch Test2"; break; default: consoleText = "Swirch TestDefault"; break; } Console.WriteLine(consoleText); } public enum TestEnum { Test1, Test2, Test3, }
Switch式だとこうなる Caseやbreakがなくなって、かなりすっきちとした書き方になった
public static void SwitchExpressionDemo(TestEnum e) { string consoleText = e switch { TestEnum.Test1 => "Swirch Test1", TestEnum.Test2 => "Swirch Test2", TestEnum.Test3 => "Swirch Test2", _ => "Swirch TestDefault", }; Console.WriteLine(consoleText); } public enum TestEnum { Test1, Test2, Test3, }
ちなみに、VidualStudioのサジェストとして、Switch文 -> Switch式への変換を提案される (言語的にもこちらを使用してほしいのかもしれない)
パターンマッチング
パターンマッチングとして提案されているSwitch式は
(公式Docにもswitchキーワードを使ったパターン マッチング式
と紹介されている)
以下のような下記かたもできる(これらはSwitch文でもできる)
public static void SwitchExpressionDemo2(int a) { string consoleText = a switch { 0 => "a は 0", > 0 => "a は0 未満", <= 0 => "a は0以下", }; Console.WriteLine(consoleText); }
また、ケース ガードが使用できるので whenを用いて柔軟に式の評価ができる
public static void SwitchExpressionDemo3(int a, int b) { string consoleText = a switch { 0 => "a は 0", > 0 when a >= b => "a は0 以上かつb以上", > 0 when a < b => "a は0 以上かつ0未満", }; Console.WriteLine(consoleText); }
型によるパターンマッチング
型によるパターンマッチングも可能で、 (これはSwich文でもできる) 例えば基底クラスMainとそれを継承したSubAとSubBというクラスがあるとき
public class Main { public string MainParam { get; set; } = ""; } public class SubA : Main { public string SubParamA { get; set; } = ""; } public class SubB : Main { public string SubParamB { get; set; } = "";
以下のように、クラスによって処理を分岐できる
public static void SwitchExpressionDemo4(Main obj) { string consoleText = obj switch { SubA => "SubA", SubB => "SubB", Main => "Main", }; Console.WriteLine(consoleText); }
網羅判定
Switch式の評価が網羅されているかの評価として 破棄パターン(_)を仕様しない方法がある
Switch式は破棄パターンは条件一致しないときの処理を行うが、
破棄パターンがなく、かつ条件網羅されていない場合はランタイムエラーが発生されるため、
条件網羅が容易になる
この辺は、TypeScriptのnever形を使用したSwitch文の網羅チェックに近いものを感じる