A cosa serve ApplicationException in .NET?


172

Per generare eccezioni, di solito utilizzo classi di eccezioni integrate, ad esempio ArgumentNullExceptione NotSupportedException. Tuttavia, a volte ho bisogno di usare un'eccezione personalizzata e in quel caso scrivo:

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

e così via. Poi lancio e prendo questi nel mio codice. Ma oggi mi sono imbattuto nella ApplicationExceptionclasse - dovrei usarlo invece? Per cosa è?

Sembra inefficiente avere molte classi di eccezione effettivamente identiche con nomi diversi (di solito non ho bisogno di alcuna funzionalità individuale). Ma non mi piace l'idea di catturare un generico ApplicationExceptione di dover usare un codice aggiuntivo per determinare quale fosse l'errore.

Dove dovrebbe ApplicationExceptionadattarsi al mio codice?


Risposte:


100

Secondo le osservazioni in msdn:

Le applicazioni utente, non il Common Language Runtime, generano eccezioni personalizzate derivate dalla classe ApplicationException. La classe ApplicationException distingue tra le eccezioni definite dalle applicazioni rispetto alle eccezioni definite dal sistema.

Se si sta progettando un'applicazione che deve creare le proprie eccezioni, si consiglia di derivare eccezioni personalizzate dalla classe Exception. Inizialmente si pensava che le eccezioni personalizzate dovessero derivare dalla classe ApplicationException; tuttavia, in pratica, non è stato riscontrato che ciò aggiunga un valore significativo. Per ulteriori informazioni, consultare Best practice per la gestione delle eccezioni.

Derivali da Exception. Inoltre, non vedo alcun problema con la creazione di nuove eccezioni per i casi, a condizione che sia garantito. Se si riscontra un caso in cui esiste già un'eccezione nel framework, utilizzare tale, altrimenti, rollare il proprio.


9
Quindi sembra che ApplicationExceptionsia inutile ed esiste solo a causa della retrocompatibilità?
Beatles1692,

La nuova documentazione MSDN, almeno 4.7.2, non rileva questa osservazione. Grazie per il qutoe: D
Alex

147

La risposta breve è: da nessuna parte.

È una reliquia del passato, in cui Microsoft intendeva che gli sviluppatori ereditassero tutte le loro eccezioni personalizzate da ApplicationException. Poco dopo, hanno cambiato idea e hanno avvertito che le eccezioni personalizzate dovrebbero derivare dalla classe di eccezione di base. Vedi le migliori pratiche per la gestione delle eccezioni su MSDN.

Uno dei motivi più ampiamente diffusi per questo deriva da un estratto di Jeffery Richter in Framework Design Guidelines :

System.ApplicationException è una classe che non dovrebbe far parte di .NET Framework. L'idea originale era che le classi derivate da SystemException avrebbero indicato eccezioni generate dal CLR (o dal sistema) stesso, mentre le eccezioni non CLR sarebbero derivate da ApplicationException . Tuttavia, molte classi di eccezione non hanno seguito questo schema. Ad esempio, TargetInvocationException (che viene generato dal CLR) deriva da ApplicationException . Quindi, la classe ApplicationException ha perso tutto il significato. Il motivo per derivare da questa classe di base è consentire ad alcuni codici più in alto nello stack di chiamate di catturare la classe di base. Non è stato più possibile rilevare tutte le eccezioni dell'applicazione.

Così il gioco è fatto. La sintesi è che ApplicationException non è dannosa , ma solo inutile .


2
Qualcuno sa perché ? Sembra che avrebbe senso in modo da poter visualizzare le eccezioni dell'app ma non le eccezioni "programmatore rovinato".
Josh Kodroff,

9
A proposito, da questa spiegazione sembra che questo non sia un cattivo design in sé ma che MSFT abbia rovinato l'implementazione. Qualcun altro lo legge allo stesso modo?
Josh Kodroff,

8
@JoshKodroff: Penso che il problema sia che se l'applicazione Whizbangdecide di voler avere tutte le sue eccezioni in una gerarchia comune, l'utilizzo ApplicationExceptiona tale scopo non offrirebbe alcun vantaggio rispetto all'utilizzo di una WhizbangExceptionclasse base personalizzata . Il problema più serio nella gerarchia di eccezioni di .net non è ApplicationException, tuttavia, ma con l'incapacità di separare le eccezioni in categorie probabilmente fatali per l'applicazione, probabilmente fatali per i thread e relative a problemi locali, insieme all'incapacità di avere significative eccezioni "composite".
supercat

@JoshKodroff: In un quadro un'eccezione correttamente progettato, IMHO, se un'eccezione si butta nel finallyblocco mentre un'altra eccezione è in attesa, catchi blocchi più in alto lo stack di chiamata deve essere attivato se corrispondono alcuna eccezione annidata, ma lasciare altre eccezioni in sospeso in modo che in uscita un catchblocco procederebbe a un altro catchblocco all'interno dello stesso tryblocco (se ce ne fosse uno adatto), e uscire da un finallyblocco con eventuali eccezioni in sospeso salterebbe al successivo esterno catcho finally.
supercat

2
@JoshKodroff C'è un'altra cosa che mi sorprende non attirare più attenzione. Cos'è veramente una "applicazione"? Che dire delle librerie di terze parti ? Poiché questi non fanno parte del framework .Net, dovrebbero, secondo le linee guida originali, ereditare da ApplicationException. Ora, quando si utilizza quella libreria nella propria applicazione e si creano anche le proprie ApplicationExceptions, non è più possibile discernere le proprie eccezioni dall'eccezione della libreria in base a ciò. Quindi è inutile. Invece, ogni componente dovrebbe semplicemente definire il proprio tipo di base di eccezione, come descrive supercat.
Oskar Berggren,

22

Nella progettazione iniziale, in .NET 1.0, era stato pianificato che il framework stesso avrebbe lanciato SystemExceptione derivato; mentre le applicazioni utente verranno generate ApplicationExceptione derivate.

Ma più tardi, in .NET 2.0, è stato eliminato.

Quindi derivano da Exception.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.