C#の例外フィルタ(when節)の使い方を詳しく解説!初心者向け完全ガイド
生徒
「C#で例外処理をするときに、条件によってキャッチするかどうかを変えられるって聞いたんですが、本当ですか?」
先生
「はい、その通りです。C#には例外フィルタ(when節)という機能があり、例外が発生したときに条件をつけて処理を分けることができます。」
生徒
「普通のtry-catchと何が違うんですか?」
先生
「普通のcatchでは発生した例外の種類で分けますが、when節を使うともっと細かく、例外の内容や状況に応じて条件分岐できるんです。例を見てみましょう。」
1. C#の例外フィルタ(when節)とは?
C#の例外フィルタ(when節)は、catchに条件をつけられる仕組みです。通常のtry-catchでは、例外の種類ごとに処理を分けます。しかし、例えば「同じ例外クラスでも、エラーメッセージの内容によって対応を変えたい」といったケースがあります。そんなときに役立つのがwhenです。
イメージしやすいように例えると、「交通違反をした人を捕まえるときに、スピード違反なら注意、信号無視なら罰金」とルールを分けるのではなく、「スピード違反でも20km/h未満なら注意、20km/h以上なら免許停止」とさらに条件を細かくするようなものです。
2. 例外フィルタの基本的な書き方
例外フィルタは、catchブロックの後にwhenをつけて条件を書くだけです。条件に当てはまったときだけ、そのcatchが実行されます。
try
{
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[5]); // 範囲外アクセス
}
catch (IndexOutOfRangeException ex) when (ex.Message.Contains("インデックス"))
{
Console.WriteLine("日本語のエラーメッセージを検出しました。");
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("インデックス範囲外のエラーが発生しました。");
}
インデックス範囲外のエラーが発生しました。
このコードでは、IndexOutOfRangeExceptionが発生したときに、エラーメッセージの内容で条件分岐しています。when節の条件がfalseなら、次のcatchに処理が回ります。
3. ログだけ取りたいときの使い方
現場でよく使われるのが「ログだけ取りたい」というケースです。つまり、例外はそのまま上に投げたいけれど、途中で一度だけ記録を残したいときです。このときもwhen節が便利です。
try
{
int x = 0;
int y = 10 / x; // 0除算
}
catch (DivideByZeroException ex) when (LogException(ex))
{
// このcatchブロックは実行されない
// LogExceptionの戻り値trueによって、例外は再スローされる
}
static bool LogException(Exception ex)
{
Console.WriteLine($"ログ出力: {ex.Message}");
return false; // falseにすることでcatch本文は実行されない
}
ログ出力: Attempted to divide by zero.
未処理の例外: System.DivideByZeroException
この仕組みを使えば、プログラムの動作を邪魔せずにログだけ残せます。初心者の方にとっては難しく感じるかもしれませんが、「whenは条件判定に使える」と覚えておけばOKです。
4. 複数条件を組み合わせて使う
whenでは、if文と同じように論理演算子(&&や||)を使って条件を組み合わせることができます。例えば「特定のユーザーIDのときだけ特別なエラーメッセージを出す」といった使い方です。
string userId = "guest";
try
{
throw new UnauthorizedAccessException("アクセス拒否されました。");
}
catch (UnauthorizedAccessException ex) when (userId == "admin")
{
Console.WriteLine("管理者権限が必要です。");
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine("一般ユーザーのアクセスは拒否されました。");
}
一般ユーザーのアクセスは拒否されました。
このように、例外フィルタを使うと「例外の種類 × 条件」で柔軟なエラーハンドリングが可能になります。
5. 例外フィルタを使うメリット
最後に、例外フィルタを使うメリットを整理します。
- コードの見通しがよくなり、複雑なif文をcatchの中に書かなくて済む
- 例外を「種類+条件」で分岐できるので柔軟性が高い
- ログ出力など「副作用だけを発生させて処理はスルーする」使い方ができる
- パフォーマンス面でも効率的で、catchの中で余計な処理をする必要がない
例外フィルタは、初心者には少し難しく見えるかもしれませんが、「例外処理をもっと細かくコントロールする方法」と理解しておけば安心です。
まとめ
例外フィルタを使いこなして柔軟なエラーハンドリングを実現しよう
C#の例外処理は、初心者の方にとって理解のハードルが高いように感じられることがあります。しかし、例外フィルタの基本的な仕組みや書き方を押さえると、例外に対する考え方が大きく変わり、複雑なエラーでも落ち着いて対処できるようになります。たとえば、例外の種類だけでは判断できない細かい状況を条件として扱いたいとき、通常のcatch節だけでは十分に整理できない場面が出てきます。そのようなときに強力に役立つのが、今回取り上げた例外フィルタ(when節)です。 例外フィルタは「例外の種類 × 条件」の組み合わせで分岐させられるため、一般的なtry-catchでは表現しきれない状況を丁寧に扱いやすくなります。特に、エラーメッセージの内容を参照したいときや、特定のユーザー状態や外部環境に応じてエラー処理を切り替えたいときに便利です。こうした書き方ができると、コードの読みやすさが大幅に改善され、メンテナンス性も向上します。
when節を活用した条件分岐の理解を深める
when節では、if文と同じように論理演算子を使い、複数の条件を組み合わせることができます。条件式がtrueのときだけcatch節が実行されるため、適切に条件を整えることで、不要なcatchを通らずにすみ、プログラムの流れが明確になります。また、エラーを判定する条件にログ出力処理を含めると、catchを書かずに記録だけ実施して例外はそのままスローする、といった柔軟な操作も行えます。このような動作は通常のtry-catchだけでは表現が難しく、例外フィルタの特性を活かした高度な活用例として非常に重要なテクニックです。
実際のサンプルコードで動きを確認してみよう
次のサンプルは、when節を利用して例外の内容を細かく判別しつつ、プログラムの流れを整理する方法を示した例です。例外フィルタを使うと、例外情報を条件式の中で参照できるため、複雑な分岐もシンプルにまとめられます。条件に一致するかどうかだけで動きが変わるため、catch内部を整理しやすい点も魅力です。
// when節を利用した例外フィルタのサンプル
try
{
string mode = "guest";
throw new UnauthorizedAccessException("アクセスが拒否されました。");
}
catch (UnauthorizedAccessException ex) when (mode == "admin")
{
Console.WriteLine("管理者のみが利用できる機能です。");
}
catch (UnauthorizedAccessException ex) when (ex.Message.Contains("拒否"))
{
Console.WriteLine("アクセスが拒否されました。特別な条件を確認してください。");
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine("一般的なアクセス拒否エラーです。");
}
このように、例外の内容や外部の状況変数を組み合わせた条件を設定することで、エラーハンドリングの幅が大きく広がります。特に例外フィルタを使うことで、catch節を過度に増やす必要がなくなり、コードの見通しがよくなります。わかりやすい処理に整理されていれば、後からコードを読むときにも理解しやすく、チーム開発にも良い影響を与えます。また、ログ出力だけを実施する使い方は、実務でも採用されるケースが多く、学んでおく価値が高い機能です。
例外フィルタがもたらすメリットと実践的な使い方
例外フィルタには、複雑な条件を簡潔に記述できるという大きな利点があります。例外処理では、例外の種類だけで判断するのが難しいケースがいくつも存在します。たとえばエラーメッセージの一部に特定の語句が含まれているかどうかを判定したい場合や、ユーザー状態や設定値によって出力メッセージを切り替えたい場面などです。そのような場合にwhen節を導入すると直感的なエラーハンドリングが可能となり、コードの品質が向上します。 また、例外フィルタはcatchの本文を実行させずにログだけ書き込む、といった独自の使い方もできるため、エラーログの追跡や監査にも役立ちます。大量の処理を行うアプリケーションでは、ログ出力と例外処理の分離はパフォーマンス改善にも貢献します。結果として、例外フィルタは初心者から中級者へとステップアップするための重要な機能と言えるでしょう。
先生と生徒の振り返り会話
生徒
「今日の内容で例外フィルタの使い方がかなり理解できました。条件によってcatchを使い分けられるのって便利ですね。」
先生
「そのとおりです。例外の内容を確認して処理を分岐させたいときに特に役立ちますよ。実務ではログ記録にも活用されることが多いですね。」
生徒
「同じ例外クラスでもメッセージの違いや条件で対応を変えられるのは新鮮でした。when節の仕組みがよくわかりました。」
先生
「例外フィルタを使えるようになると、エラー処理を自在にコントロールできるようになります。規模が大きなアプリケーションほど重要になるので、ぜひ今日の学びを生かしてみてください。」