ルール「CA1031: 一般的な例外タイプをキャッチしない」はまったく役に立ちません。(それ自体は意図ではなく、実装と説明です)
この特定のケースでは、コンストラクターがスローすることが文書化されている例外の「ほとんど」をカバーするため、より具体的なものをキャッチすることが実行可能である可能性があります。IOException
StreamReader
(ああ、待ってください。それから、によってスローされる可能性のあるすべてのものも考慮に入れる必要がありますReadToEnd
)
(ああ、待ってください。渡された文字列が空の場合に備えて、正当な例外キャッチ ケースがあるのかもしれません。つまり、それを明示的にテストするのではなく、一般的にキャッチしたいのです。)ArgumentException
それ以外で:
与えられた例を大まかに考えると、気にするのはファイルの読み取りが失敗したことだけです-IFFが失敗した場合は、呼び出しチェーンでそれを伝える必要があります。
繰り返します:ファイルの読み取りが失敗したこと、およびその理由が二次的なものであることをコール チェーンに伝えたいと考えています。
ファイルの読み取り (処理) が失敗したとき:例外がスローされたとき。
したがって、本当にやりたいことは、例外をキャッチし、やりたいことでコンテキスト化して (たとえば、ファイル名を追加して)、何がうまくいかなかったのか、なぜうまくいかなかったのかを示す何かを返すか再スローすることです(それは実際の "内部」例外)。
このため、例は(ほぼ)スポットです:
- この場合の「コール チェーンを上る」とは、ユーザーが直接コンソールにいることです。
- エラーを「ユーザー」が読み取る文字列として「返し」ます。これは、単純なコンソールプログラムに適しています。
- 何がうまくいかなかったのかを明確に伝えます。(ただし、渡されたファイル名を含める必要があります
StreamReader
。)
- 失敗した理由、つまり例外メッセージが含まれています。(コール スタックも含める必要がある可能性があります。)
例:
この例はもう少し複雑で、ファイル名はユーザーが指定したものだとします。空の文字列は、(a) 通常のケースであり、おそらく (b)コードでの特別な処理を保証しないユーザー エラーです。完全に十分です。
上で推奨されているようにキャッチするだけIOException
では、ユーザーが空のファイル名を入力すると、アプリケーションがクラッシュするか、他の catch ブロックと本質的に同じことを行う追加の catch ブロックが必要になります: ファイルの読み取りが失敗したこととその理由を報告します。
独立した観察: この素晴らしい作品を見つけました: http://www.codeproject.com/Articles/7557/Exception-Handling-in-C-with-the-quot-Do-Not-Catchここで、著者は確かに私よりも建設的です「まったく役に立たない」ステートメントですが、本質的に同様の結論があります(別の、確かに有効な解決策があります):(emph。追加)
Microsoft のガイドラインに従う場合、File.Copy
メソッドによってトリガーされる可能性のある例外のみをキャッチする必要があります。.NET Framework のクラス ライブラリを見ると、これが UnauthorizedAccessException (...) であることがわかります。あなたが私に尋ねると、これらすべての例外を個別にキャッチすることはできません。私が知りたかったのは、ファイルのコピーが失敗したかどうかだけです。IOException、ArgumentException、および NotSupportedException (他のすべての例外はこれら 3 つの例外から派生するため) のみをキャプチャするだけで十分ですが、これを知るにはドキュメントをもう一度読む必要があります。単純にファイルをコピーするのに、それほど苦労したくありません。
ガイドラインは、実行されたタスクによってスローされる可能性のあるすべての例外を知っていることを前提としています。ファイルのコピーは、Microsoft によって適切に文書化されている非常に単純な操作です。しかし、サードパーティのツールを使用している場合はどうなるでしょうか? 無人ツールの安定性は、このツールのドキュメントの品質に依存します。このサードパーティが、ツールがスローする例外の 1 つをドキュメントに記載するのを忘れた場合、無人アプリケーションが途中で停止する可能性があります。