例外
概要
処理中に発生した異常を例外(Exception)という形で上流の処理に通知できます。
通知された側は例外に応じて適切なハンドリングを行うことで、プログラム実行中の異常をコントロールします。
ただし、例外は重たい処理なので、要否を適切に判断する必要があります。
例外の定義
すべての例外はExceptionクラスを継承して定義されます。
public class HogeException : Exception { }
発生した異常の種類に応じた例外クラスを定義します。
- IOException
- SqlException etc...
例外の通知
例外クラスのインスタンスをスローします。
メッセージなどを指定可能です。
throw new HogeException("Exception occurred");
例外のハンドリング
try/catchステートメントでハンドリングします。
try { throw new HogeException(); } catch { Console.WriteLine("Exception occurred") }
例外の種類を指定したり、フィルターすることができます。
複数の例外のハンドリング処理を記述することもできま
す。
catch (HogeException e) { // 例外がHogeExceptionの場合に処理する Console.WriteLine(e.Message); } catch (FugaException e) when (e.Message == "a") { // 例外がFugaExceptionかつ、Messageの値が"a"の場合に処理する } catch (FugaException e) when (e.Message == "b") { // 例外がFugaExceptionかつ、Messageの値が"b"の場合に処理する } catch (Exception e) { // それ以外の場合に処理する }
上流で確実に処理される場合を除き、漏れを防ぐためにException型のハンドリング処理を入れます。
例外がハンドリングされなかった場合、アプリケーションは強制終了されてしまいます。
例外の再スロー
例外をcatchし、ログ出力などの処理を行った後に再スローすることができます。
ただし、再スロー方法次第では、スタックトレースのオリジナルの例外発生箇所の情報が失われます。
以下の方法でそれを回避することができます。
- 何も指定せずにスローする
catch (HogeException ex) { throw; }
- catchした例外インスタンスをInnerExceptionとする例外をスローする
catch (HogeException ex) { throw new HogeException(ex); }
- ExceptionDispatchInfoを使用する
catch (HogeException ex) { ExceptionDispatchInfo.Capture(ex).Throw(); }
catchした例外インスタンスを指定してスローした場合、スタックトレースが失われます。
再スローされた例外は再スロー箇所を例外発生箇所としてスタックトレースに記録します。
catch (HogeException ex) { throw ex; }