オブジェクト指向超入門〜第11回〜

前回はJAVAにおける例外に対するポリシーを考えてみました。今回はC#について。

C#では全ての例外クラスについて、throws宣言はいらないしキャッチしなくても誰にも怒られない、という文法になっています。JAVAの例外ポリシーを「もっともだ」と理解した人からすると、これはいかにも乱暴な仕様に思えます。しかしこれは言語設計者のポリシーの違いによるものなのだと考えると、なんとなくわかる気もしてくるのです。

JAVAではErrorとRuntimeExceptionだけが想定外のエラーであり、それ以外はあらかじめ可能性を予見できるのだから、それ相応のエラー処理をcatchブロック内で実装しておくべきだ、という思想なのでした。C#では例外とは全てあらかじめ予見できないものであり、プログラムを書いてる段階で予想できるようなモンはハナからアプリレベルでちゃんとエラー処理を実装しとけよ、という思想なのです。そうなると関数内でおきた業務仕様レベルのエラーを呼び出し元に知らせる為の手段として例外を使うというのは間違った使い方であり、関数内で起きたエラーは旧来のやり方どおり、やはり戻り値で知らせるのが正しい作法なのか?という疑問が生まれます。実は私もこの疑問でハマった経験があります。しばらくの間この問題に頭を悩ませた結果たどりついた結論は、何のことはない「やっぱり関数内のエラーは例外で返すべき」という当たり前の話なのでした。

C#の文法をよく読めばすぐにわかりますが「例外をキャッチしなくていいよ」とは書いてありますが「キャッチしちゃ駄目」とは言っていません。そして例外が起こったのにキャッチしなかった場合にはプログラムが落ちる、という動作についてはJAVAと同じです。
あらかじめ想定できる例外、つまり関数内のコードに「Throw〜」と書いてある例外については、その関数の仕様として明示すべきだし、そのような関数を呼び出す側では、発生する可能性を予見できる事象なのだから、その例外はキャッチすべきです。
どの関数でどんな種類の例外が発生するのかはケースバイケースであって、よってどの例外はキャッチしなくて良いorしなきゃ駄目、というのはコードを書いてるプログラマだけが知っている事情です。それなのに例外クラスの継承ツリーなどという言語設計者の個人的な思想でもって個々のプログラマの裁量を奪っているJAVAに比べて、C#はより洗練されていて、プログラマの自由度に最大限配慮されているのかなぁ、と納得してくるのでした。