C#:適切なタイプの例外をスローすることに関する記事
質問
時々私は魔女のタイプの例外を知らないか、私が投げるべきです。したがって、私は通常例外を投げます()。これについての素敵な記事はありますか?
解決
エラーから回復しようとしていない場合は、 Exception
何がうまくいかなかったかを伝える文字列で。 (または、どのエラーが発生したかに関係なく、同じアクションを実行する場合)。
プログラマーにメッセージに入れるのではなく、新しい例外名を使用することで何が間違っているかを明らかにする以外に、例外は特定の例外から回復するのに役立つデータを含めることができます。
たとえば、an ArgumentNullException
プロパティがあります ParamName
, 、例外をスローするときに設定する必要があります。発信者がそれをキャッチすると、彼はこのプロパティを調べて、エラーを引き起こした引数の新しい値を渡すか、関連するエラーを印刷してプログラマーに何がうまくいかなかったかを印刷することができます。
不幸なことに、例外が潜在能力を最大限に発揮することはめったになく(多くのオープンソースAPIなど)、多くの場合、プログラマーに何がうまくいかなかったかを知らせるために単に挿入されます。あなたが読む予定がない場合、これら2つの間に大きな違いはありません ParamName
あなたがそれを捕まえるときのプロパティ。 (多くの人は気にせず、キャッチするだけです Exception
とりあえず)。
throw new ArgumentNullException("arg1");
throw new Exception("arg1 is null");
エラーから完全に回復することは難しい場合がありますが、一部のアプリケーションでは、必要なすべての詳細を提供できるカスタム例外を作成することが望ましい場合があります。
とりあえず、私はただ置くでしょう Exception
VSのオブジェクトブラウザ検索に、すでに何があるかを確認してください。彼らの名前はかなり自明なので、適切なものを選ぶことができるはずです。
他のヒント
一般的な例外を投げることの問題は、コードの能力をスタックのさらに上に制限して適切に処理することです(つまり、ベストプラクティスは、倒れる前に可能な限り最も具体的な例外をトラップし、処理できるもののみをキャプチャすることです)。
Jeffrey Richterには、例外処理に関する優れたセクションがあります(System.Exceptionネームスペースに関する情報を含む) C#経由のCLR
まあ、あなたがすべきではないことの1つは投げることです Exception
自体。
常に適切なサブクラスを探してください。
どの例外がいつスローするかを綴る出版物はわかりませんが ArgumentException
と InvalidOperationException
ほとんどのケースの世話をする必要があります。
それらが登場した場合、個別のケースについて個別の質問をしてください。
システムの状態に基づいて、例外をいくつかのカテゴリに分割することをお勧めします。
- この方法は、何もしなかったほどの方法で失敗しました。基礎となるデータの状態は妨げられず、おそらく有効です。典型的なシナリオ:コレクションから存在しないオブジェクトを取得しようとするか、既にあるオブジェクトを追加しようとします。別の考えられるシナリオ:データの損失を引き起こすべきではない場合の通信タイムアウト(そして、問題が単に反対側が単純に遅すぎるということである場合、操作を再試行していた可能性があります)。
- この方法は、基礎となるデータ構造を乱した可能性のある方法で失敗しました。または、基礎となるデータ構造が以前に破損していた可能性があります。検証するための手順が取られない限り、このデータ構造では、さらなる操作を試みるべきではありません。別の可能なシナリオ:レコードが部分的に取得されたときに通信タイムアウトが発生し、部分的に再取得されたデータが失われるようになりました。プロトコルに応じて、接続でリカバリアクションを実行するか、それを閉じて新しいものを開始する必要がある場合があります。
- システムの状態に何かが深刻な問題があり、回復は不可能です。
残念ながら、既存の.NET例外はそのパターンのようなものには適合しません。 threadabortexception、cpuhascaughtfireexception、および「通常」の例外などのタイプ例外ベースがあれば、それは良かったでしょう。私はそのようなデザインで.NET 4.0がややKludgeであることを理解していますが、正確なメカニズムはわかりません。いずれにせよ、私は、各グループのすべての例外が他のグループとは異なる共通の祖先を共有しているため、ユーザー定義の例外を上記のようにグループに分割する必要があることを提案します。
Krzysztof Cwalina(「Microsoftの.NETフレームワークチームの主要なアーキテクト」)の記事があります。 スローするための適切なタイプの例外を選択します それはこれに光を当てます。それは、スローするための適切な例外を選択することと、カスタム例外の作成に関するガイダンスを扱っています。