SwitchExpressionException の原因と直し方
switch式が全てのパターンを網羅していないとき、コンパイラは警告を出しますが止めません。網羅されていない値が実際に渡された瞬間に実行時エラーになります。
エラーメッセージの読み方
Unhandled exception. System.Runtime.CompilerServices.SwitchExpressionException: Non-exhaustive switch expression failed to match its input.
System.Runtime.CompilerServices- 名前空間 — System なら標準の基本例外です
SwitchExpressionException- 例外クラス — 何が起きたか。ここを検索するのが最短です
Non-exhaustive switch expression failed to match its input.- 詳細メッセージ — どの値が問題だったか
at Program.Describe(Int32 n) in Program.cs:line 3- 発生箇所 — スタックトレースの先頭行
このエラーが出る典型パターン
パターン1
1 class Program { 2 static string Describe(int n) { 3 return n switch { 4 1 => "one", 5 2 => "two", 6 }; 7 } 8 static void Main(string[] args) { 9 System.Console.WriteLine(Describe(3)); ^ 10 } 11 }
Unhandled exception. System.Runtime.CompilerServices.SwitchExpressionException: Non-exhaustive switch expression failed to match its input.
at Program.Describe(Int32 n) in Program.cs:line 3
switch式は網羅していないパターンがあると、そこに来たときだけ実行時に失敗します。コンパイラは警告は出しますが止めてはくれません。
直し方: 3 を 1 にします。
広告
広告スロット(未設定)
パターン2
1 class Program { 2 static string Grade(int score) { 3 return score switch { 4 90 => "A", 5 80 => "B", 6 70 => "C", 7 }; 8 } 9 static void Main(string[] args) { 10 System.Console.WriteLine(Grade(60)); ^ 11 } 12 }
Unhandled exception. System.Runtime.CompilerServices.SwitchExpressionException: Non-exhaustive switch expression failed to match its input.
at Program.Grade(Int32 score) in Program.cs:line 3
点数を細かく分岐させるほど、想定外の値を見落としやすくなります。_ => "..."のような既定パターンを最後に置くと防げます。
直し方: 60 を 80 にします。
パターン3
1 class Program { 2 static string Label(int code) { 3 return code switch { 4 200 => "OK", 5 404 => "Not Found", 6 }; 7 } 8 static void Main(string[] args) { 9 System.Console.WriteLine(Label(500)); ^ 10 } 11 }
Unhandled exception. System.Runtime.CompilerServices.SwitchExpressionException: Non-exhaustive switch expression failed to match its input.
at Program.Label(Int32 code) in Program.cs:line 3
HTTPステータスコードのように種類が多い値をswitch式で扱うときほど、既定パターンの用意が重要になります。
直し方: 500 を 200 にします。
よくある誤解
警告(CS8509)が出ていても、ビルドは成功してしまいます。見た目上は正常に動くコードに見えるため、想定外の入力が来るまで気づきにくいバグです。
まとめ
SwitchExpressionExceptionは上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。