¿Para qué es ApplicationException en .NET?

172

Para lanzar excepciones, generalmente uso clases de excepción incorporadas, por ejemplo, ArgumentNullExceptiony NotSupportedException. Sin embargo, a veces necesito usar una excepción personalizada y en ese caso escribo:

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

y así. Luego lanzo y atrapo estos en mi código. Pero hoy me encontré con elApplicationException clase, ¿debería usar eso en su lugar? ¿Para qué sirve?

Parece ineficiente tener muchas clases de excepción efectivamente idénticas con nombres diferentes (generalmente no necesito ninguna funcionalidad individual). Pero no me gusta la idea de atrapar un genéricoApplicationException y tener que usar un código adicional para determinar cuál fue el error.

¿Dónde debería ApplicationExceptionencajar mi código?

James
fuente

Respuestas:

100

De acuerdo con los comentarios en msdn:

Las aplicaciones de usuario, no el Common Language Runtime, lanzan excepciones personalizadas derivadas de la clase ApplicationException. La clase ApplicationException diferencia entre excepciones definidas por aplicaciones frente a excepciones definidas por el sistema.

Si está diseñando una aplicación que necesita crear sus propias excepciones, se recomienda derivar excepciones personalizadas de la clase Excepción. Originalmente se pensó que las excepciones personalizadas deberían derivarse de la clase ApplicationException; sin embargo, en la práctica no se ha encontrado que agregue un valor significativo. Para obtener más información, consulte Mejores prácticas para manejar excepciones.

Derivarlos de Exception. Además, no veo ningún problema con la creación de nuevas excepciones para sus casos, siempre que esté justificado. Si encuentra un caso en el que ya hay una excepción en el marco, utilícelo, de lo contrario, cree el suyo.

Femaref
fuente
9
Entonces, ¿parece que ApplicationExceptiones inútil y existe simplemente por la compatibilidad con versiones anteriores?
Beatles1692
La nueva documentación de MSDN, al menos 4.7.2, pierde este comentario. Gracias por el qutoe: D
Alex
147

La respuesta corta es: en ninguna parte.

Es una reliquia del pasado, donde Microsoft pretendía que los desarrolladores heredaran todas sus excepciones personalizadas de ApplicationException. Poco después, cambiaron de opinión y aconsejaron que las excepciones personalizadas se derivaran de la clase de excepción base. Consulte las mejores prácticas para manejar excepciones en MSDN.

Una de las razones más ampliamente difundidas para esto proviene de un ejercicio de Jeffery Richter en las Directrices de diseño de marcos :

System.ApplicationException es una clase que no debe formar parte de .NET Framework. La idea original era que las clases derivadas de SystemException indicarían excepciones lanzadas desde el CLR (o sistema) en sí mismo, mientras que las excepciones no CLR se derivarían de ApplicationException . Sin embargo, muchas clases de excepción no siguieron este patrón. Por ejemplo, TargetInvocationException (que es lanzado por el CLR) se deriva de ApplicationException . Entonces, la clase ApplicationException perdió todo significado. La razón para derivar de esta clase base es permitir que algún código más arriba en la pila de llamadas capture la clase base. Ya no era posible detectar todas las excepciones de la aplicación.

Entonces ahí lo tienes. El resumen ejecutivo es que ApplicationException no es dañino , solo inútil .

Quick Joe Smith
fuente
2
¿Alguien sabe por qué es eso? Parece que tendría sentido para poder mostrar excepciones de la aplicación, pero no excepciones de "programador jodido".
Josh Kodroff
9
Por cierto, parece de esta explicación que este no es un mal diseño per se pero que MSFT arruinó la implementación. ¿Alguien más lee esto de manera similar?
Josh Kodroff
8
@JoshKodroff: Creo que el problema es que si la aplicación Whizbangdecide que quiere tener todas sus excepciones bajo una jerarquía común, usar ApplicationExceptionpara ese propósito realmente no ofrecería ninguna ventaja sobre el uso de una WhizbangExceptionclase base personalizada . Sin ApplicationExceptionembargo, el problema más grave en la jerarquía de excepciones de .net no está relacionado con la incapacidad de separar las excepciones en categorías probablemente relacionadas con la aplicación, probablemente fatales y con problemas locales, junto con la imposibilidad de tener excepciones "compuestas" significativas.
supercat
@JoshKodroff: en un marco de excepciones correctamente diseñado, en mi humilde opinión, si se lanza una excepción durante el finallybloqueo mientras hay otra excepción pendiente, los catchbloques más arriba en la pila de llamadas deben activarse si coinciden con cualquier excepción anidada, pero dejar otras excepciones pendientes para que salga un catchbloque procedería a otro catchbloque dentro del mismo trybloque (si alguno fuera adecuado), y al salir de un finallybloque con cualquier excepción pendiente saltaría al siguiente exterior catcho finally.
supercat
2
@JoshKodroff Hay una cosa más que me sorprende que no reciba más atención. ¿Qué es realmente una "aplicación"? ¿Qué pasa con las bibliotecas de terceros ? Dado que estos no son parte del marco .Net, deberían, según las pautas originales, heredar de ApplicationException. Ahora, cuando usa esa biblioteca en su aplicación y también crea sus propias excepciones de aplicación, ya no puede discernir sus propias excepciones de la excepción de la biblioteca basándose en eso. Entonces es inútil. En cambio, cada componente simplemente debe definir su propio tipo base de excepción, como describe supercat.
Oskar Berggren
22

En el diseño inicial, en .NET 1.0, se planificó que el marco mismo se lanzaría SystemExceptiony derivaría; mientras que las aplicaciones de usuario - se lanzarán ApplicationExceptiony derivarán.

Pero más tarde, en .NET 2.0, eso se descartó.

Así derivan de Exception.

abatishchev
fuente