O que é ApplicationException no .NET?

172

Para lançar exceções, eu costumo usar classes de exceção internas, por exemplo, ArgumentNullExceptione NotSupportedException. No entanto, às vezes eu preciso usar uma exceção personalizada e, nesse caso, escrevo:

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

e assim por diante. Então eu jogo e pego isso no meu código. Mas hoje me deparei com a ApplicationExceptionclasse - eu deveria estar usando isso? Para que serve isto?

Parece ineficiente ter muitas classes Exception efetivamente idênticas com nomes diferentes (geralmente não preciso de nenhuma funcionalidade individual). Mas não gosto da idéia de pegar um genérico ApplicationExceptione ter que usar código extra para determinar qual foi o erro.

Onde deve se ApplicationExceptionencaixar no meu código?

James
fonte
35
Ótima pergunta, também +1 para as exceções de amostra habilmente nomeadas
Cody Gray

Respostas:

100

De acordo com as observações no msdn:

Os aplicativos do usuário, não o Common Language Runtime, lançam exceções personalizadas derivadas da classe ApplicationException. A classe ApplicationException diferencia entre exceções definidas por aplicativos e exceções definidas pelo sistema.

Se você estiver projetando um aplicativo que precisa criar suas próprias exceções, é recomendável derivar exceções personalizadas da classe Exception. Pensou-se originalmente que exceções personalizadas deveriam derivar da classe ApplicationException; no entanto, na prática, não foi encontrado um valor significativo. Para obter mais informações, consulte Práticas recomendadas para lidar com exceções.

Derive-os de Exception. Além disso, não vejo problema em criar novas exceções para seus casos, desde que isso seja justificado. Se você encontrar um caso em que já exista uma exceção na estrutura, use isso, caso contrário, role o seu próprio.

Femaref
fonte
9
Então, parece que ApplicationExceptioné inútil e existe apenas por causa da compatibilidade com versões anteriores?
precisa saber é o seguinte
A nova documentação do MSDN, pelo menos 4.7.2, perde essa observação. Obrigado pelo qutoe: D
Alex
147

A resposta curta é: nenhum lugar.

É uma relíquia do passado, em que a Microsoft pretendia que os desenvolvedores herdassem todas as exceções personalizadas do ApplicationException. Logo depois, eles mudaram de idéia e aconselharam que as exceções personalizadas deveriam derivar da classe Exception básica. Consulte Práticas recomendadas para lidar com exceções no MSDN.

Uma das razões mais amplamente divulgadas para isso vem de um esforço de Jeffery Richter nas Diretrizes de Design da Estrutura :

System.ApplicationException é uma classe que não deve fazer parte do .NET Framework. A ideia original era que as classes derivadas de SystemException indicariam exceções geradas pelo próprio CLR (ou sistema), enquanto as exceções não-CLR seriam derivadas de ApplicationException . No entanto, muitas classes de exceção não seguiram esse padrão. Por exemplo, TargetInvocationException (lançado pelo CLR) é derivado de ApplicationException . Portanto, a classe ApplicationException perdeu todo o significado. O motivo para derivar dessa classe base é permitir que algum código mais alto na pilha de chamadas capture a classe base. Não era mais possível capturar todas as exceções de aplicativos.

Então aí está. O resumo executivo é que ApplicationException não é prejudicial , apenas inútil .

Quick Joe Smith
fonte
2
Alguém sabe por que isso é? Parece que faria sentido para que você pudesse exibir exceções de aplicativos, mas não exceções de "programador estragado".
Josh Kodroff
9
BTW, parece a partir desta explicação que este não é um projeto ruim em si, mas que o MSFT estragou a implementação. Alguém mais leu isso da mesma forma?
21712 Josh Kodroff
8
@ JoshKodroff: Eu acho que o problema é que, se o aplicativo Whizbangdecidir que deseja ter todas as suas exceções sob uma hierarquia comum, o uso ApplicationExceptionpara esse fim não ofereceria realmente nenhuma vantagem sobre o uso de uma WhizbangExceptionclasse base personalizada . O problema mais sério na hierarquia de exceções do .net não está no ApplicationExceptionentanto, mas com a falha em separar as exceções em categorias relacionadas ao problema, provavelmente fatal de aplicativo, provavelmente fatal de thread e local, além da incapacidade de ter exceções "compostas" significativas.
30812
@JoshKodroff: Em uma estrutura de exceção projetada adequadamente, o IMHO, se uma exceção for lançada durante o finallybloco enquanto outra exceção estiver pendente, os catchblocos mais adiante na pilha de chamadas deverão ser acionados se corresponderem a qualquer exceção aninhada, mas deixar outras exceções pendentes para que a saída um catchbloco prosseguiria para outro catchbloco dentro do mesmo trybloco (se houver algum), e sair de um finallybloco com qualquer exceção pendente passaria para o próximo externo catchou finally.
30812 supercat
2
@ JoshKodroff Há mais uma coisa que me surpreende e não recebe mais atenção. O que é realmente um "aplicativo"? E as bibliotecas de terceiros ? Como eles não fazem parte da estrutura .Net, eles devem, pelas diretrizes originais, herdar do ApplicationException. Agora, quando você usa essa biblioteca em seu aplicativo e também cria suas próprias ApplicationExceptions, não é mais possível discernir suas próprias exceções da exceção da biblioteca com base nisso. Então é inútil. Em vez disso, cada componente deve simplesmente definir seu próprio tipo de base de exceção, como descreve o supercat.
Oskar Berggren
22

No design inicial, no .NET 1.0, foi planejado que a própria estrutura fosse lançada SystemExceptione derivada; enquanto aplicativos de usuário - lançaráApplicationException e derivados.

Mas, mais tarde, no .NET 2.0, isso foi descartado.

Derivam assim Exception.

abatishchev
fonte