Gestione delle eccezioni (Guida per programmatori C#)
Aggiornamento: novembre 2007
I programmatori di C# utilizzano un blocco try per suddividere il codice che potrebbe essere interessato da un'eccezione e i blocchi catch per gestire le eventuali eccezioni risultanti. I blocchi finally possono essere utilizzati per eseguire il codice indipendentemente dal verificarsi di eventuali eccezioni. Questa situazione è talvolta necessaria perché il codice che segue un costrutto try/catch non verrà eseguito se viene generata un'eccezione. Un blocco try deve essere utilizzato con un blocco catch o finally e può includere più blocchi catch. Esempio:
try
{
// Code to try here.
}
catch (SomeSpecificException ex)
{
// Code to handle exception here.
// Only catch exceptions you know how to handle.
// Never catch base class System.Exception without
// rethrowing it at the end of the catch block.
}
try
{
// Code to try here.
}
finally
{
// Code to execute after try here.
}
try
{
// Code to try here.
}
catch (SomeSpecificException ex)
{
// Code to handle exception here.
}
finally
{
// Code to execute after try (and possibly catch) here.
}
Un'istruzione try senza un blocco catch o finally genera un errore del compilatore.
Blocchi catch
Un blocco catch consente di specificare un tipo di eccezione da intercettare. Questo tipo viene chiamato filtro eccezionie deve essere un tipo derivato da Exception. In generale, non specificare Exception in un blocco catch a meno che si sappia per certo come gestire tutte le eccezioni che potrebbero essere generate nel blocco try o a meno che si includa un'istruzione throw alla fine del blocco catch.
È possibile concatenare più blocchi catch con filtri eccezioni differenti. I diversi blocchi catch vengono valutati dall'alto verso il basso, ma viene eseguito un solo blocco catch per ogni eccezione generata, in particolare il primo blocco catch che specifica il tipo esatto o una classe base dell'eccezione generata. Se nessun blocco catch specifica un filtro eccezioni corrispondente, verrà eseguito un eventuale blocco catch senza filtro. È importante posizionare per primi i blocchi catch con le classi di eccezioni più specifiche, ovvero più derivate.
È necessario intercettare le eccezioni quando le condizioni seguenti sono vere:
Si dispone di informazioni specifiche sul motivo per cui è stata generata l'eccezione ed è possibile implementare un recupero specifico, ad esempio intercettare un oggetto FileNotFoundException e richiedere all'utente di immettere un nuovo nome di file.
È possibile creare e generare una nuova eccezione più specifica. Esempio:
int GetInt(int[] array, int index) { try { return array[index]; } catch(System.IndexOutOfRangeException e) { throw new System.ArgumentOutOfRangeException( "Parameter index is out of range."); } }
Per gestire parzialmente un'eccezione. È ad esempio possibile utilizzare un blocco catch per aggiungere una voce nel log degli errori, ma in questo caso è necessario generare nuovamente l'eccezione per consentirne la successiva gestione. Esempio:
try { // try to access a resource } catch (System.UnauthorizedAccessException e) { LogError(e); // call a custom error logging procedure throw e; // re-throw the error }
Blocchi finally
Un blocco finally consente la pulitura delle operazioni eseguite in un blocco try. Se presente, il blocco finally viene eseguito dopo i blocchi try e catch. Un blocco finally viene sempre eseguito, sia che venga o meno generata un'eccezione o che venga o meno individuato un blocco catch che corrisponde al tipo di eccezione.
Il blocco finally può essere utilizzato per rilasciare risorse quali flussi di file, connessioni di database e handle di elementi grafici senza attendere che il Garbage Collector del runtime finalizzi gli oggetti. Per ulteriori informazioni, vedere Istruzione using (Riferimenti per C#).
Nell'esempio riportato di seguito viene utilizzato il blocco finally per chiudere un file aperto nel blocco try. Si noti che prima della chiusura viene controllato lo stato dell'handle del file. Se il blocco try non apre il file, l'handle del file sarà comunque impostato su null. In alternativa, se il file viene aperto correttamente e non vengono generate eccezioni, il blocco finally verrà comunque eseguito e chiuderà il file aperto.
System.IO.FileStream file = null;
System.IO.FileInfo fileinfo = new System.IO.FileInfo("C:\\file.txt");
try
{
file = fileinfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// check for null because OpenWrite
// might have failed
if (file != null)
{
file.Close();
}
}
Specifiche del linguaggio C#
Per ulteriori informazioni, vedere le seguenti sezioni incluse in Specifiche del linguaggio C#:
16 Eccezioni
8.9.5 Istruzione throw
8.10 Istruzione try
Vedere anche
Concetti
Riferimenti
Eccezioni e gestione delle eccezioni (Guida per programmatori C#)
try-catch (Riferimenti per C#)
try-finally (Riferimenti per C#)
try-catch-finally (Riferimenti per C#)