.NETのApplicationExceptionとは何ですか?


172

例外をスローするには、通常、組み込みの例外クラスを使用します(例:ArgumentNullExceptionおよび)NotSupportedException。ただし、カスタム例外を使用する必要がある場合があり、その場合は次のように記述します。

class SlippedOnABananaException : Exception { }
class ChokedOnAnAppleException : Exception { }

等々。次に、これらをコードにスローしてキャッチします。しかし、今日私はApplicationExceptionクラスに出くわしました-代わりにそれを使うべきですか?何のために?

異なる名前の効果的に同一のExceptionクラスを多数持つことは非効率的に見えます(通常、個別の機能は必要ありません)。しかし、私はジェネリックをキャッチしApplicationException、エラーが何であるかを決定するために追加のコードを使用しなければならないという考えを嫌います。

ApplicationException私のコードはどこに合わせる必要がありますか?


35
すばらしい質問、巧妙に名前が付けられたサンプルの例外にも+1
Cody Grey

回答:


100

msdn の発言によると:

共通言語ランタイムではなく、ユーザーアプリケーションがApplicationExceptionクラスから派生したカスタム例外をスローします。ApplicationExceptionクラスは、アプリケーションによって定義された例外とシステムによって定義された例外を区別します。

独自の例外を作成する必要があるアプリケーションを設計している場合は、Exceptionクラスからカスタム例外を派生させることをお勧めします。当初、カスタム例外はApplicationExceptionクラスから派生する必要があると考えられていました。ただし、実際には、これが重要な価値を追加することはありません。詳細については、「例外処理のベストプラクティス」を参照してください。

から派生しますException。また、保証されている限り、ケースの新しい例外の作成に問題はありません。フレームワークですでに例外が発生している場合は、それを使用してください。それ以外の場合は、独自にロールしてください。


9
だからそれApplicationExceptionは役に立たないと思われ、単に下位互換性のためにあるのですか?
Beatles1692

新しいMSDNドキュメント(少なくとも4.7.2)はこの発言を見逃しています。Qutoeをありがとう:D
Alex

147

簡単に言えば、どこにもありません。

これは、Microsoftが開発者にApplicationExceptionからすべてのカスタム例外を継承することを意図した過去の遺物です。その直後、彼らは考えを変え、カスタム例外は基本のExceptionクラスから派生するべきだとアドバイスしました。MSDNの例外処理のベストプラクティスを参照してください。

これがより広く流通する理由の1つは、フレームワーク設計ガイドラインの Jeffery Richterからの抜粋です。

System.ApplicationExceptionは、.NET Frameworkの一部であってはならないクラスです。もともとの考え方は、SystemExceptionから派生したクラスはCLR(またはシステム)自体からスローされた例外を示し、CLR以外の例外はApplicationExceptionから派生するというものでした。ただし、多くの例外クラスはこのパターンに従っていませんでした。たとえば、TargetInvocationException(CLRによってスローされます)はApplicationExceptionから派生します。そのため、ApplicationExceptionクラスはすべての意味を失いました。この基本クラスから派生する理由は、基本クラスをキャッチするために、呼び出しスタックの上位にあるコードを許可するためです。すべてのアプリケーション例外をキャッチすることができなくなりました。

だからあなたはそれを持っています。エグゼクティブサマリーは、ApplicationExceptionは有害ではなく、役に立たないということです。


2
それがなぜなのか誰か知っていますか?アプリの例外を表示できても、「プログラマーがねじ込まれた」例外を表示できないようにするのは理にかなっているようです。
Josh Kodroff、2012

9
ところで、この説明から、これはそれ自体は悪い設計ではなく、MSFTが実装を台無しにしたと思われます。他の誰かがこれを同様に読んでいますか?
Josh Kodroff

8
@JoshKodroff:問題は、アプリケーションWhizbangがすべての例外をいくつかの共通の階層の下に置きたいと決定した場合ApplicationException、その目的のために使用しても、カスタムWhizbangException基本クラスを使用するよりもメリットが少ないことだと思います。ただし、.netの例外階層のより深刻な問題はにありませんがApplicationException、例外を、おそらくアプリケーション致命的、おそらくスレッド致命的、およびローカル問題関連のカテゴリに分類できないことに加えて、意味のある「複合」例外。
スーパーキャット2012

@JoshKodroff:適切に設計された例外フレームワークであるIMHOでは、finallyブロック中に別の例外が保留されているときに例外がスローされたcatch場合、ネストされた例外と一致する場合、呼び出しスタックのさらに上のブロックがトリガーされますが、他の例外は保留のままにして終了しますcatchブロックは、他に進むであろうcatch同じ内のブロックtry(いずれも適していた場合)ブロック、及び出射finally次の外側にジャンプになる保留中の例外を除いて、ブロックcatchまたはfinally
スーパーキャット2012

2
@JoshKodroffもう1つ注意すべきことがないのに驚いたことがあります。本当に「アプリケーション」とは何ですか?サードパーティのライブラリはどうですか?これらは.Netフレームワークの一部ではないため、元のガイドラインではApplicationExceptionから継承する必要があります。アプリケーションでそのライブラリを使用し、独自のApplicationExceptionを作成すると、それに基づいてライブラリの例外から独自の例外を識別できなくなります。だからそれは役に立たない。代わりに、supercatで説明されているように、各コンポーネントは独自の例外ベースタイプを定義するだけです。
Oskar Berggren 2017年

22

最初の設計では、.NET 1.0では、フレームワーク自体がスローされSystemExceptionて派生することが計画されていました。一方、ユーザーアプリケーション-スローApplicationExceptionして派生します。

しかし、後に.NET 2.0では、それは削除されました。

したがって、から派生しExceptionます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.