Excepción abstracta tipo super

17

Si lanzar System.Exceptionse considera tan malo, ¿por qué no se Exceptionhizo abstracten primer lugar?

De esa manera, no sería posible llamar:

throw new Exception("Error occurred.");

Esto exigiría el uso de excepciones derivadas para proporcionar más detalles sobre el error que ocurrió.

Por ejemplo, cuando quiero proporcionar una jerarquía de excepción personalizada para una biblioteca, generalmente declaro una clase base abstracta para mis excepciones:

public abstract class CustomExceptionBase : Exception
{
    /* some stuff here */
}

Y luego alguna excepción derivada con un propósito más específico:

public class DerivedCustomException : CustomExceptionBase
{
    /* some more specific stuff here */
}

Luego, al llamar a cualquier método de biblioteca, uno podría tener este bloque genérico try / catch para detectar directamente cualquier error proveniente de la biblioteca:

try
{
    /* library calls here */
}
catch (CustomExceptionBase ex)
{
    /* exception handling */
}

¿Es esta una buena practica?

¿Sería bueno si Exceptionse hiciera abstracto?

EDITAR: Mi punto aquí es que incluso si se marca una clase de excepción abstract, aún puede atraparla en un bloque general. Hacerlo abstracto es solo una forma de prohibir a los programadores lanzar una excepción "súper amplia". Por lo general, cuando lanza voluntariamente una excepción, debe saber de qué tipo es y por qué sucedió. Por lo tanto, hacer cumplir un tipo de excepción más específico.

marco-fiset
fuente
3
+1 "La mejor manera de evitar el uso incorrecto es hacer que dicho uso sea imposible". - Scott Meyers
Steven Jeuris
3
"¿Sería bueno si Exception se hiciera abstracto?" - Absolutamente no, porque todo el código .NET existente que usa una nueva Excepción ("...") se rompería. Sin embargo, "¿Debería el equipo .NET haber hecho Excepción abstracta para empezar?" - Probablemente, sí, pero ahora es> 10 años demasiado tarde :)
MattDavey

Respuestas:

11

No sé las razones reales por las que se hizo de esta manera, y en cierto grado estoy de acuerdo en que evitar que se produzcan infinitas excepciones sería algo bueno.

PERO ... al codificar pequeñas aplicaciones de demostración o prueba de conceptos, no quiero comenzar a diseñar 10 subclases de excepción diferentes, o pasar tiempo tratando de decidir cuál es la "mejor" clase de excepción para la situación. Prefiero simplemente tirar Exceptiony pasar una cadena que explica los detalles. Cuando sea el código de usar y tirar, no se preocupan por estas cosas y si estaba obligado a cuidar de esas cosas, yo tampoco creo mi propia GenericExceptionclase y echo de que en todas partes, o mover a una herramienta / idioma diferente. Para algunos proyectos, estoy de acuerdo en que crear correctamente las subclases de excepción relevantes es importante, pero no todos los proyectos lo requieren.

FrustratedWithFormsDesigner
fuente
Estoy completamente de acuerdo con usted, pero la pregunta era pensar implícitamente en proyectos no triviales.
marco-fiset
3

Posibilidad A: es lógicamente correcto.

Tiene razón en que Microsoft, junto con muchos otros, no sugiere lanzar un new Exception() directamente por una gran cantidad de razones.

Dicho esto, podemos considerar el ideal académico de que el propósito de una Exceptionjerarquía de clases es definir un efecto de reducción para que solo se puedan detectar las excepciones más específicas. ( ArgumentNullExceptiones decir, es más angosto queArgumentException ).

La clase de excepción no es una excepción (juego de palabras no previsto). Se pretende que sea la excepción más amplia posible, una "súper excepción" que casi no se puede atrapar porque su alcance es infinitamente amplio. 'Excepción' no esabstract en el sentido de que la Excepción no pueda existir como una entidad por sí sola. Puede (aunque es cierto que todavía no se han definido buenos casos; consulte la posibilidad B) y, por lo tanto, debe ser públicamente constructible.

La palabra clave 'abstracta' (en un sentido puramente académico) solo es aplicable cuando la clase base no tiene sentido por sí sola, es decir FourLeggedAnimal .

Todo esto en mente, no habría una razón técnica para hacer la clase abstract, aparte de ser una fuente de molestia para los desarrolladores. .

Posibilidad B: Bloqueo de diseño / No sabían

Si la EM hizo que esta clase fuera abstracta, podrían haber tenido problemas si cambiaran de opinión en el futuro, ya que esta clase es muy esencial para los fundamentos del lenguaje. Ya se burlaron ApplicationException, por lo que es previsible que anticiparan un cambio en la recomendación en el futuro también. (ver http://blogs.msdn.com/b/kcwalina/archive/2006/06/23/644822.aspx )

Puede haber otras razones (creo que tal vez esto tenga que ver con Reflection, o alguna otra razón técnica), por lo que estoy haciendo esta publicación un CW.

Kevin McCormick
fuente
"Solo porque es" súper amplio ", no es abstracto". ... Pero ese es el argumento del OP, ¿no? ¿No debería ser abstracto en el sentido de que siempre se debe pasar alguna indicación del tipo de excepción?
Steven Jeuris
Buen punto, actualizaré mi respuesta en consecuencia: la naturaleza de esta pregunta es un poco confusa porque 'abstracto' es tanto una palabra clave del lenguaje como el nombre del concepto que se está discutiendo.
Kevin McCormick
@KevinMcCormick: el término 'resumen' aquí se usa como la palabra clave del idioma. ¿Dime cómo puedo cambiar mi pregunta para que sea más clara para futuros lectores?
marco-fiset
Creo que es una gran pregunta. Cualquier conversión OO con respecto a la abstractpalabra clave golpea este muro. No estoy seguro de alguna forma de evitarlo, aparte de denotar la abstractpalabra clave con los backticks.
Kevin McCormick
2
¿Cómo es "desabstraer" una clase un cambio radical?
configurador