- 目的
- 項目45:契約違反を例外として報告すること
- 項目47:アプリケーション固有の例外クラスを作成する
- 項目49:catchからの再スローよりも例外フィルタを使用すること
- 項目50:例外フィルタの副作用を活用する
- 所感
目的
流し読みにならないように、1項目毎要約をする。
今回は、最後の5章:例外処理まとめ。
項目45:契約違反を例外として報告すること
例外がスローされた場合でも堅牢なコードを作成するスキルは、すべてのC#開発者にとって重要です。
- 例外を発生させる可能性があるPublicメソッドを開発する場合、その処理の事前チェック用のメソッドも提供するようにするとよい。
- 例外処理をフロー制御に利用してはいけない。・・・そういえば、以前、例外処理をGOTO文のようにして実装されたシステムを見たことがあった・・・例外処理は通常のメソッド呼び出しよりも多くの時間がかかるため、パフォーマンスの観点からも、可読性の観点からもアンチパターンであるということだと思う。
項目47:アプリケーション固有の例外クラスを作成する
- すべての例外処理をExceptionクラスを利用して行うことに固執せず、独自の例外クラスを作成し、適切なタイミングで、適切な例外処理を行えるようにするのがよい。 - むやみやたらに独自例外クラスを作成するのではなく、発生した例外を無視したとき、長期間にわたって例外が発生することになる場面(データの整合性がとれなくなったなど)かどうかを一つの指標として作るようにするのが良い。
項目49:catchからの再スローよりも例外フィルタを使用すること
- 例外フィルタを利用して、発生した例外の情報をより多く取得するようにする。
- 例外フィルタについては、例外フィルタと、ユーザー フィルター例外ハンドラーを使用するを参照する。
項目50:例外フィルタの副作用を活用する
- 例外フィルタを使用すると、ランタイムが適切なcatch句を見つける前にれ外フィルタを実行することができる。そのため、発生した例外を全て確認したい場合は、常にfalseを返すような例外フィルタを実装すると良い。
- 以下のようにすることで、既存のCatch句に影響を及ぼさずにログ出力機能を追加することができる。
Func<Exception, bool> errorhandling = (exception) => { var oldColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(exception.ToString()); Console.ForegroundColor = oldColor; return false; }; try { throw new ArgumentException(); } catch (SystemException ex) when (errorhandling(ex)) { //ここは実行されない Console.WriteLine(ex.ToString()); } catch (ArgumentException ex) { Console.WriteLine(ex.ToString()); } catch (Exception ex) { Console.WriteLine(ex.ToString()); }
所感
例外処理については、わかった気になっていたが、例外フィルタのように、初めて知ったテクニックもあった。今一度例外処理の考え方を見直す必要がありそう。