C#の例外メッセージの書き方はクソだ

C#の例外メッセージの書き方はクソだ。
あの例外メッセージの書き方は、例外の悪い書き方でしかない。

例えばこんなのだ。

System.NullReferenceException Object reference not set to an instance of an object.

このどこが悪いのか?
それは、理由の情報が書いてないことだ。

NullReferenceException ぬるぽが起きたらしいね。
なるほど、オブジェクトがnullだったらしい。

Nullだったということはわかる。
そうだね。nullらしいね。それじゃあ修正しよう。

では、どのオブジェクトがNULLだったのかい?

・・・・
・・・・・・・・

わかりません。
まったくわかりません。
スタックトレースに書いてある関数のどこかです。

ふさげるなっ!!



デバッグビルドだとIDEが場所で止まってくれるし、情報も吐き出される。
しかし、このダメな例外メッセージの書き方で問題になるのは、リリースビルドのときだ。

スタックトレースには、pdbがないと行番号は出力されないし、あってもなぜか出力されないこともある。
(世界は広いのでそういう変な環境もあるらしい)

よって、私たちが得られる情報は、直前に実行されていた関数内のどこかのオブジェクトがnullだったということだけだ。
どこだよそれは。

変数名はコンパイルの過程で消えるから出せない?
そうだね。確かに消えて出せない。でも、変数の型ならだせるだろう?
どの型が問題を起こしたのか?これだけでも候補を絞り込むことができる。

なんでこんな簡単なことをやらないの?


他にもダメなのがいっぱいある。
これを作った奴らはおかしい。

System.ArgumentOutOfRangeException Index was out of range.
System.Runtime.InteropServices.ExternalException A generic error occurred in GDI .

どれもこれも理由が明記されていない。
範囲外アクセスしたのはわかる。でもそれはどの型のオブジェクトで、何番目にアクセスしたから範囲外なのかといった基本的な情報が欠落している。
これはダメな例外メッセージの典型例だ。
意味が分からない例外メッセージはないと同じだ。 throw new ArgumentOutOfRangeException("fuck you"); と書いているのとほぼ同じだ。
いったいMSの開発者は何を考えていたんだ。

これを書いたMSの開発者は後で私のオフィスに来るように。


もし、このクソ仕様を受け入れるならば、関数をできるだけ小さい単位に細分化する必要がある。
1つの関数が1つのメソッドしか呼ばない程度にな。
そんな面倒なことはしてられないけど。


C#ネイティヴの例外は、起きたことはわかるんだけど、誰がなぜ起こしたのかわからない。
ダメな例外メッセージの書き方そのものだ。
C#の例外メッセージの書き方を真似しなければ、いいプログラムが書けるだろう。

C++だと黒魔術を利用して、例外ハンドラーそのものに割り込んで、もっとましな例外メッセージを追加したり、情報を多く取れるだろう。
しかし、C#の世界ではそれは不可能だ。ランタイムライブラリに割り込むことは不可能だろう。たぶん。
もし、もっとましな方法があるなら教えてほしい。

いったいどうやるのがベストプラクティスなんだ。