Condividi tramite


21 Eccezioni

21.1 Generale

Le eccezioni in C# offrono un modo strutturato, uniforme e indipendente dai tipi di gestione delle condizioni di errore a livello di sistema e a livello di applicazione.

21.2 Cause di eccezioni

Le eccezioni possono essere generate in due modi diversi.

  • Un'istruzione throw (§13.10.6) genera un'eccezione immediatamente e incondizionato. Il controllo non raggiunge mai l'istruzione immediatamente successiva a throw.
  • Alcune condizioni eccezionali che si verificano durante l'elaborazione di istruzioni ed espressioni C# causano la generazione di un'eccezione in determinate circostanze quando l'operazione non può essere completata normalmente. Vedere §21.5 per un elenco delle varie eccezioni che possono essere generate in questo modo.

    Esempio: un'operazione di divisione integer (§12.10.3) genera un'eccezione System.DivideByZeroException se il denominatore è zero. esempio finale

21.3 La classe System.Exception

La System.Exception classe è il tipo di base di tutte le eccezioni. Questa classe ha alcune proprietà rilevanti condivise da tutte le eccezioni:

  • Message è una proprietà di sola lettura di tipo string che contiene una descrizione leggibile del motivo dell'eccezione.
  • InnerException è una proprietà di sola lettura di tipo Exception. Se il valore è diversonull da , fa riferimento all'eccezione che ha causato l'eccezione corrente. In altre parole, l'eccezione corrente è stata generata in un blocco catch che gestisce . InnerException) In caso contrario, il relativo valore è null, che indica che questa eccezione non è stata causata da un'altra eccezione. Il numero di oggetti eccezione concatenati in questo modo può essere arbitrario.

Il valore di queste proprietà può essere specificato nelle chiamate al costruttore dell'istanza per System.Exception.

21.4 Modalità di gestione delle eccezioni

Le eccezioni vengono gestite da un'istruzione try (§13.11).

Quando viene generata un'eccezione (§21.2), il sistema cerca la clausola catch più vicina in grado di gestire l'eccezione, come determinato dal tipo di runtime dell'eccezione. In primo luogo, il metodo corrente viene cercato un'istruzione racchiusa try lessicalmente e le clausole associate catch dell'istruzione try vengono considerate in ordine. In caso di esito negativo, viene eseguita la ricerca di un'istruzione che racchiude try in modo lessicale il punto della chiamata al metodo corrente. Questa ricerca continua fino a quando non viene trovata una catch clausola in grado di gestire l'eccezione corrente, assegnando un nome a una classe di eccezione che è della stessa classe o di una classe base del tipo di runtime dell'eccezione generata. Una catch clausola che non denomina una classe di eccezione può gestire qualsiasi eccezione.

Dopo aver trovato una clausola corrispondente catch , il sistema prepara il trasferimento del controllo alla prima istruzione della catch clausola . Prima dell'inizio dell'esecuzione catch della clausola, il sistema esegue prima di tutto, in ordine, tutte finally le clausole associate alle try istruzioni più annidate che hanno rilevato l'eccezione.

Se non viene trovata alcuna clausola corrispondente catch :

  • Se la ricerca di una clausola corrispondente catch raggiunge un costruttore statico (§15.12) o un inizializzatore di campo statico, viene generata un'eccezione System.TypeInitializationException al punto che ha attivato la chiamata del costruttore statico. L'eccezione interna di System.TypeInitializationException contiene l'eccezione generata originariamente.
  • In caso contrario, se si verifica un'eccezione durante l'esecuzione del finalizzatore e tale eccezione non viene intercettata, il comportamento non viene specificato.
  • In caso contrario, se la ricerca di clausole corrispondenti catch raggiunge il codice che inizialmente ha avviato il thread, l'esecuzione del thread viene terminata. L'impatto di tale terminazione è definito dall'implementazione.

21.5 Classi di eccezioni comuni

Le eccezioni seguenti vengono generate da determinate operazioni C#.

Tipo di eccezione Descrizione
System.ArithmeticException Classe di base per le eccezioni che si verificano durante operazioni aritmetiche, quali System.DivideByZeroException e System.OverflowException.
System.ArrayTypeMismatchException Generata quando un archivio in una matrice ha esito negativo perché il tipo dell'elemento archiviato non è compatibile con il tipo della matrice.
System.DivideByZeroException Generata quando si verifica un tentativo di dividere un valore integrale per zero.
System.IndexOutOfRangeException Generata quando un tentativo di indicizzazione di una matrice tramite un indice minore di zero o all'esterno dei limiti della matrice.
System.InvalidCastException Generata quando una conversione esplicita da un tipo di base o un'interfaccia a un tipo derivato ha esito negativo in fase di esecuzione.
System.NullReferenceException Generata quando viene utilizzato un null riferimento in modo da rendere obbligatorio l'oggetto a cui si fa riferimento.
System.OutOfMemoryException Generata quando un tentativo di allocare memoria (tramite new) non riesce.
System.OverflowException Generata quando si verifica un overflow di un'operazione aritmetica in un contesto checked.
System.StackOverflowException Generata quando lo stack di esecuzione viene esaurito con troppe chiamate in sospeso; in genere indicativo di ricorsione molto profonda o non associato.
System.TypeInitializationException Generata quando un costruttore statico o un inizializzatore di campo statico genera un'eccezione e non esiste alcuna catch clausola per intercettarla.