.NET言語の例外事情

エラーの発生および処理のガイドライン

こんなページ見つけた。

このページによると・・・

ほとんどの場合は、定義済みの例外の型を使用します。新しい型の例外を定義するのは、クラス ライブラリを使用する開発者がその新しい例外型をキャッチし、その型自体に基づいてプログラムによるアクションを実行することが想定される場合だけに限ります。この方法は、例外文字列を解析する代わりに使用します。例外文字列を解析すると、パフォーマンスと保守性に悪影響を与えることになります。

エラーの発生および処理のガイドライン

.NETではMS自体が標準の例外を積極的に使え、と言っているようだ。

正しい文法と句読点を使用して、エラー メッセージを作成します。例外の説明文字列の文章は、句点で終了する必要があります。例外メッセージを汎用的に表示するコードでは、開発者が最後の句点を忘れた場合に対処する必要はありません。

エラーの発生および処理のガイドライン

なんでこんなことまで。しかも理由が書いてない。これに従っても害はないし、これまでも例外の説明文字列は句点で終わるようにしていたから、問題はないけど。

特に、一般的なエラーが発生した場合は、null を返すようにします。たとえば、File.Open コマンドは、ファイルが見つからない場合に null 参照を返しますが、ファイルがロックされている場合は例外をスローします。

エラーの発生および処理のガイドライン

うーん、nullを返すことには抵抗が・・・
これに関してはNullObjectが返せる場合は積極的にNullObjectを使いたい。

内部例外 (チェインされた例外) を使用します。ただし、補足情報を追加する場合や、例外の型を変更する場合以外は、例外をキャッチして再スローすることは避けてください。

エラーの発生および処理のガイドライン

これも微妙だ。例外をキャッチしてオブジェクトの状態を戻し、キャッチした例外を再スローするのは避けるべきか、やるべきかの二択ならやるべきだろう*1
これは「例外をキャッチして補足情報の追加なしに例外をラップし、その例外をスローする」ことを避けろ、と言っているのかもしれないけど*2

NullReferenceException または IndexOutOfRangeException をスローするメソッドは作成しないでください。

エラーの発生および処理のガイドライン

最初はなんでこんなことを言うのか全く理解できなかったけど、最後に載ってる例外の表を見ると、ArgumentNullException、ArgumentOutOfRangeExceptionというのがある。おそらく、こちらを使え、ということだろう。
確かに、JavaでNullPointerExceptionを投げたいのは、nullを許さない引数にnullが指定された場合しかないような気がする。

ただし、Javaでは明示的にnullチェックを行う場合と明示的にnullチェックを行わない場合のどちらでもNullPointerExceptionが発生するが、.NET言語では明示的にnullチェックを行った場合はArgumentNullExceptionが、明示的にnullチェックを行わなかった場合はNullReferenceExceptionが発生することになる。
この場合、.NET言語ではNullReferenceExceptionを投げるメソッドは作成するべきではないから、nullを許さない引数は全てnullチェックする必要が出てくる。
これをちゃんとやってる人が果たして何人いるのやら・・・


例外階層は、Exceptionを継承したSystemExceptionとApplicationExceptionが来て、それ以外の例外はこのどちらかを継承することになるようだ。
ただし、基本的にはApplicationExceptionから派生し、System名前空間*3で独自の例外を作るときだけSystemExceptionから派生するように作るらしい。

*1:常に、ではないけど。不可能な場合もあるし。

*2:原文どこよ・・・

*3:Javaでいうjava.langパッケージのような存在。Javaとは違い、C#では名前空間を実際のディレクトリ階層と結び付けていないので、System名前空間内に独自のクラス等を作ることが出来る。JavaよりC++名前空間に近いけど、C#ではSystem名前空間であろうと何追加してもいいのかな?