À quoi sert ApplicationException dans .NET?

172

Pour lever des exceptions, j'utilise généralement des classes d'exceptions intégrées, par exemple ArgumentNullExceptionet NotSupportedException. Cependant, parfois j'ai besoin d'utiliser une exception personnalisée et dans ce cas j'écris:

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

etc. Ensuite, je lance et attrape ces derniers dans mon code. Mais aujourd'hui, je suis tombé sur la ApplicationExceptionclasse - devrais-je utiliser cela à la place? C'est pour quoi?

Il semble inefficace d'avoir beaucoup de classes d'exception effectivement identiques avec des noms différents (je n'ai généralement pas besoin de fonctionnalité individuelle). Mais je n'aime pas l'idée d'attraper un générique ApplicationExceptionet d'avoir à utiliser du code supplémentaire pour déterminer quelle était l'erreur.

Où doit ApplicationExceptions'inscrire mon code?

James
la source

Réponses:

100

Selon les remarques dans msdn:

Les applications utilisateur, et non le Common Language Runtime, lancent des exceptions personnalisées dérivées de la classe ApplicationException. La classe ApplicationException fait la différence entre les exceptions définies par les applications et les exceptions définies par le système.

Si vous concevez une application qui doit créer ses propres exceptions, il est conseillé de dériver des exceptions personnalisées à partir de la classe Exception. On pensait à l'origine que les exceptions personnalisées devraient dériver de la classe ApplicationException; cependant, dans la pratique, cela ne s'est pas avéré apporter une valeur ajoutée significative. Pour plus d'informations, consultez Meilleures pratiques pour la gestion des exceptions.

Tirez-les de Exception. De plus, je ne vois pas de problème avec la création de nouvelles exceptions pour vos cas, tant que cela est justifié. Si vous rencontrez un cas où il y a déjà une exception dans le framework, utilisez-la, sinon, lancez la vôtre.

Femaref
la source
9
Il semble donc que ce ApplicationExceptionsoit inutile et existe-t-il simplement à cause de la compatibilité ascendante?
Beatles1692
La nouvelle documentation MSDN, au moins 4.7.2, manque cette remarque. Merci pour le qutoe: D
Alex
147

La réponse courte est: nulle part.

C'est une relique du passé, où Microsoft voulait que les développeurs héritent de toutes leurs exceptions personnalisées d'ApplicationException. Peu de temps après, ils ont changé d'avis et ont indiqué que les exceptions personnalisées devraient dériver de la classe Exception de base. Consultez Meilleures pratiques pour gérer les exceptions sur MSDN.

L'une des raisons les plus largement diffusées à cet égard provient d'un extrait de Jeffery Richter dans Framework Design Guidelines :

System.ApplicationException est une classe qui ne doit pas faire partie du .NET Framework. L'idée originale était que les classes dérivées de SystemException indiqueraient les exceptions levées à partir du CLR (ou du système) lui-même, tandis que les exceptions non CLR seraient dérivées d' ApplicationException . Cependant, de nombreuses classes d'exception n'ont pas suivi ce modèle. Par exemple, TargetInvocationException (qui est levée par le CLR) est dérivé d' ApplicationException . Ainsi, la classe ApplicationException a perdu toute signification. La raison de dériver de cette classe de base est de permettre à du code plus haut dans la pile d'appels d'attraper la classe de base. Il n'était plus possible d'attraper toutes les exceptions d'application.

Alors là vous l'avez. Le résumé analytique est qu'ApplicationException n'est pas nuisible , juste inutile .

Joe Smith rapide
la source
2
Quelqu'un sait-il pourquoi ? Il semble que cela ait du sens pour que vous puissiez afficher les exceptions App mais pas les exceptions "programmeur foutu".
Josh Kodroff
9
BTW, il semble d'après cette explication que ce n'est pas une mauvaise conception en soi, mais que MSFT a foiré la mise en œuvre. Est-ce que quelqu'un d'autre lit cela de la même manière?
Josh Kodroff
8
@JoshKodroff: Je pense que le problème est que si l'application Whizbangdécide qu'elle veut avoir toutes ses exceptions sous une hiérarchie commune, utiliser ApplicationExceptionà cette fin n'offrirait vraiment aucun avantage par rapport à l'utilisation d'une WhizbangExceptionclasse de base personnalisée . Le problème le plus grave dans la hiérarchie des exceptions de .net n'est pas ApplicationException, cependant, mais avec l'échec de la séparation des exceptions en catégories probablement fatales pour l'application, probablement fatales pour les threads et liées aux problèmes locaux, ainsi que l'incapacité d'avoir exceptions «composites» significatives.
supercat
@JoshKodroff: Dans un cadre d'exceptions correctement conçu, à mon humble avis, si une exception est levée pendant le finallyblocage alors qu'une autre exception est en attente, les catchblocs plus haut dans la pile d'appels doivent être déclenchés s'ils correspondent à une exception imbriquée, mais laissez les autres exceptions en attente afin que la sortie un catchbloc passerait à un autre catchbloc dans le même trybloc (le cas échéant), et quitter un finallybloc avec toutes les exceptions en attente sauterait au prochain bloc catchou finally.
supercat
2
@JoshKodroff Il y a encore une chose dont je suis surpris de ne pas attirer plus d'attention. Qu'est-ce qu'une "application" vraiment? Qu'en est-il des bibliothèques tierces ? Étant donné qu'ils ne font pas partie du framework .Net, ils devraient, selon les directives d'origine, hériter d'ApplicationException. Désormais, lorsque vous utilisez cette bibliothèque dans votre application et que vous créez également vos propres ApplicationExceptions, vous ne pouvez plus discerner vos propres exceptions de l'exception de la bibliothèque en fonction de cela. Donc c'est inutile. Au lieu de cela, chaque composant doit simplement définir son propre type de base d'exception, comme le décrit supercat.
Oskar Berggren
22

Dans la conception initiale, dans .NET 1.0, il était prévu que le framework lui-même soit lancé SystemExceptionet dérivé; tandis que les applications utilisateur - jettera ApplicationExceptionet dérivé.

Mais plus tard, dans .NET 2.0, cela a été abandonné.

Ainsi dérivent de Exception.

abatishchev
la source