本ブログは更新を停止しました。Aerieをよろしくお願いいたします。
投稿カレンダーはJavaScriptが有効でない環境では使用できません。
αετο? / aetos / あえとす
シャノン? 誰それ。
埼玉を馬鹿にする奴は俺が許さん。
基本的に知ったかぶり。興味を持った技術に手を出して、ちょっと齧りはするものの、それを応用して何か形にするまでは及ばずに飽きて放り出す人。
例外指定とは、「この関数はこんな例外を投げますよ」という宣言である。
今のところ、C++は宣言はできるが、守ることは強制されない。C#にはそもそも例外指定がない。使い物になるのはJavaくらいのものである。
どうして、例外指定が必要なのか。答えは単純。 そうでもしなければ、リファレンスにまともな例外が書かれないからだorz
投稿日時 : 2006年12月27日 15:56
throws ktkr!
修正で新しく例外が追加されるとそれを使ってる メソッドを順々に例外指定していくハメになるので、 業務で使うと、他人のモジュールに影響を与えないように 決められた例外に丸めて投げる仕様になって、 意味を成さなかった経験がorz
だから例外系統は設計初期から考慮しておかなければならない。 オブジェクト指向もそう。 行き当たりばったりで修正してるからいけない。 でもたぶん、世の中そんなのばっかりorz
コードに記載しなくてもコンパイラがメタデータに書き込んでくれたらいいんじゃない? 「コンパイラさん、がんばって」 そう思います メタデータにあれば、コンパイル時に参照元から取ってくるのもできるだろうし、開発者がコードに記載する必要はあるのかなぁ
できれば設計時に固めて、あとは変更なしでお願いしたいんですけどね。インターフェイスだから。 俺としては、コンパイル時に未処理例外があるとして警告を出すよりも、何をしたらどんな例外が出るのかドキュメントにきちっと書いてほしいんです。これが主目的。 メタデータがあれば、そこからドキュメントを生成するツールでドキュメンテーションを強制することはできるでしょうが、例外仕様がインターフェイスじゃなくて実装詳細になったら、悪く言えば改版ごとに投げる例外変え放題になったら、ドキュメントがどうなるか…。 .NET でも Win32 でもアセンブリの概念があることで、リンク相手となる DLL のバージョンは固定できるから、一度把握すれば投げてくる例外は変わらない(改版ごとに投げる例外が変わっても、そもそも新版をリンクしない)と考えてもいいですが、それならそれで、インターフェイスに互換性が無くなる変更を加える前のドキュメントも当面の間は公開しておいて貰わないと困る。
私自身が理解しているわけではないですが。Java の例外は、.NET Framework には存在しません。.NET Framework の例外は、Java のエラーに相当します。 このことをふまえて。 .NET Framework では、「検査例外」は戻り値として定義するか、あらかじめ検査メソッドを通過させるように設計します。検査メソッドを通過させるなら、本処理メソッドでは「業務例外」として扱えます。 詳しくは、赤間本を。
> 私自身が理解しているわけではないですが。Java の例外は、.NET Framework には存在しません。.NET Framework の例外は、Java のエラーに相当します。 俺もJavaはロクに知らずに言ってますが、そういうわけでもないような。 ぐぐったら出てきたサイト http://www.javaroad.jp/java_exception1.htm によると、「エラー」の例として「OutOfMemory」、「RuntimeException」の例として「NullPointerException」、「その他のException」の例として「IOException」が挙げられていますが、.NET Framework では、これらのいずれに相当するものも「例外」として存在します。 また、「Javaのエラー」とは「ひとたび発生したら復旧が不可能であるもの」でしょう。だから捕捉しなくても文句を言われない。 .NET の例外が Java のエラーに相当するのであれば、.NET に例外処理という機構はないはずです。 > .NET Framework では、「検査例外」は戻り値として定義するか メソッドが失敗したことを戻り値で返すという方針は欠陥であると考えます。 設計によってはどうしても失敗を示す特別な値が返せない場合があるからです。 COM のように、戻り値は成否判定だけに徹底させ、本来返したい値は引数を通じてと言うのであれば別ですが。 > 検査メソッドを通過させるなら、本処理メソッドでは「業務例外」として扱えます。 > 詳しくは、赤間本を。 赤間本なるものを所持していないので、「業務例外」なるものが何なのかわかりません。 あれですか、先日同盟内で「当たった!当たった!」って騒ぎになってた。 Amazonで調べたら、Web系の本を書いてる方のようで。あまり興味のない分野です。
>メソッドが失敗したことを戻り値で返すという方針は欠陥であると考えます。 >設計によってはどうしても失敗を示す特別な値が返せない場合があるからです。 私は一概にそうとはいえないと考えます。 たとえば、ParseとTryParseのように目的で使い分けるものもありますし、NetworkStreamのReadメソッドのように例外が出たら抜けるというスタイルもどうかと思います。 またStream.EndOfStreamやドラッグドロップの処理のように事前に他のメソッドで例外が起きないかどうか調べるスタイルもあります。 それに、try-catchブロックは必要以上にコードを複雑にするのであまり使いたくないというのも本音です。
> たとえば、ParseとTryParseのように目的で使い分けるものもありますし、 TryParseが変換できなかった場合にfalseを返すのは「失敗」ではないと考えます。 TryParseは「変換できるかどうか調べる」ことを念頭に置いたメソッドですから「変換できない」という結果は予期したものであり、COMで言えばS_FALSEに当たると言えましょう。 Parseはそうではなく「変換する」メソッドですから、変換できないのはすなわち失敗です。 ちなみに個人的には、TryParseがParse結果を返すのは気に入りません。変換はParseに任せて、TryParseはCanParsableとでも言うべき役割であって欲しかった。 > NetworkStreamのReadメソッドのように例外が出たら抜けるというスタイルもどうかと思います。 よくわかりませんでした。どういうことでしょうか? > 事前に他のメソッドで例外が起きないかどうか調べるスタイルもあります。 これであれば尚更です。 事前に他のメソッドで失敗するケースを弾いておけば、メソッドが失敗するということは(予期しないエラーが発生しない限り)ありえないわけですから、戻り値はvoidにすべきです。
予想外に紛糾してしまいました。 結局のところ、本題は、エラー処理の方針がどうであれ、「ちゃんとドキュメントしとけ」ということが言いたかったわけですから、それさえ守られればいいかなと。 例外の使い方に関しては、また別のトピックを設けることにしましょう。
Powered by: Copyright © αετος / aetos