Super tipo de exceção abstrata

17

Se jogar System.Exceptioné considerado tão ruim, por que não foi Exceptionfeito abstractem primeiro lugar?

Dessa forma, não seria possível chamar:

throw new Exception("Error occurred.");

Isso aplicaria o uso de exceções derivadas para fornecer mais detalhes sobre o erro que ocorreu.

Por exemplo, quando quero fornecer uma hierarquia de exceção personalizada para uma biblioteca, geralmente declaro uma classe base abstrata para minhas exceções:

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

E então alguma exceção derivada com um objetivo mais específico:

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

Então, ao chamar qualquer método de biblioteca, pode-se ter esse bloco try / catch genérico para capturar diretamente qualquer erro proveniente da biblioteca:

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

Esta é uma boa prática?

Seria bom se Exceptionfosse feito abstrato?

EDIT: Meu argumento aqui é que, mesmo que uma classe de exceção seja marcada abstract, você ainda pode capturá-la em um bloco catch-all. Tornar isso abstrato é apenas uma maneira de proibir os programadores de lançar uma exceção "super ampla". Geralmente, quando você voluntariamente lança uma exceção, deve saber que tipo é e por que aconteceu. Forçando assim a lançar um tipo de exceção mais específico.

marco-fiset
fonte
3
+1 "A melhor maneira de impedir o uso incorreto é tornar esse uso impossível." - Meyers Scott
Steven Jeuris
3
"Seria bom se a exceção fosse feita abstrata?" - Absolutamente não, porque todo o código .NET existente que usa a nova exceção ("...") seria interrompido. No entanto, "A equipe do .NET deve ter tornado o Exception abstrato?" - Provavelmente, sim, mas é> 10 anos tarde demais :)
MattDavey

Respostas:

11

Não sei as razões reais pelas quais isso foi feito dessa maneira e, em certo grau, concordo que impedir que exceções infintamente amplas sejam lançadas seria uma coisa boa.

MAS ... ao codificar pequenos aplicativos de demonstração ou prova de conceitos, não quero começar a projetar 10 subclasses de exceção diferentes ou gastar tempo tentando decidir qual é a "melhor" classe de exceção para a situação. Prefiro jogar Exceptione passar uma string que explica os detalhes. Quando se do código de usar e deitar fora, eu não me importo com essas coisas e se eu foi forçado para se preocupar com tais coisas, eu quer criar minha própria GenericExceptionclasse e jogar que em todos os lugares, ou mudar para uma ferramenta / linguagem diferente. Para alguns projetos, concordo que a criação adequada de subclasses de exceção relevantes é importante, mas nem todos os projetos exigem isso.

FrustratedWithFormsDesigner
fonte
Concordo plenamente com você, mas a pergunta estava implicitamente pensando em projetos não triviais.
marco-Fiset
3

Possibilidade A: É logicamente correto.

Você está certo de que a Microsoft, juntamente com muitos outros, não sugere jogar new Exception()diretamente por uma infinidade de razões.

Dito isto, podemos considerar o ideal acadêmico de que o objetivo de uma Exceptionhierarquia de classe é definir um efeito restritivo, de modo que apenas as exceções mais específicas possam ser detectadas. (ou seja, ArgumentNullExceptioné mais estreito que ArgumentException).

A classe Exception não é exceção (trocadilho não se destina). Pretende ser a exceção mais ampla possível, uma "super exceção" que quase não pode ser capturada porque seu escopo é infinitamente amplo. 'Exceção' não é abstractno sentido de que a exceção não possa existir como uma entidade por si só. Pode (embora, reconhecidamente, ainda não estejam definidos bons casos - ver Possibilidade B) e, portanto, deve ser publicamente construtível.

A palavra-chave 'abstrata' (no sentido puramente acadêmico) só é aplicável quando a classe base não faz sentido por si só - ie FourLeggedAnimal.

Tudo isso em mente, não haveria razão técnica para fazer a classe abstract, além de ser uma fonte de agravamento para os desenvolvedores .

Possibilidade B: Design Lock-in / Eles não sabiam

Se a MS tornou essa classe abstrata, eles podem ter tido problemas se mudassem de idéia no futuro, pois essa classe é muito essencial para os fundamentos da linguagem. Eles já brincaram ApplicationException, então é previsível que eles antecipem uma mudança na recomendação no futuro. (consulte http://blogs.msdn.com/b/kcwalina/archive/2006/06/23/644822.aspx )

Pode haver outras razões (acho que talvez isso tenha a ver com Reflexão, ou alguma outra razão técnica), por isso estou fazendo deste post um CW.

Kevin McCormick
fonte
"Só porque é" super amplo ", não é abstrato." ... Mas esse é o argumento do OP, não é? Não deveria ser abstrato no sentido de que sempre é preciso passar alguma indicação do tipo de exceção.
91111 Steven Jeuris
Bom ponto, atualizarei minha resposta de acordo - a natureza dessa pergunta é um pouco confusa porque 'abstract' é uma palavra-chave do idioma e também o nome do conceito que está sendo discutido.
21711 Kevin
@KevinMcCormick: O termo 'abstract' aqui é usado como a palavra-chave language. Diga-me como posso mudar minha pergunta para que fique mais claro para futuros leitores?
marco-Fiset
Eu acho que é uma ótima pergunta. Qualquer conversão de OO referente à abstractpalavra - chave atinge esse muro. Não tenho certeza de nenhuma maneira de contorná-lo, além de denotar a abstractpalavra-chave com os backticks.
21711 Kevin
2
Como "desagrupar" uma classe é uma mudança radical?
configurator