Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Un blocco try viene usato dai programmatori C# per partizionare il codice che potrebbe essere interessato da un'eccezione. I blocchi catch associati vengono usati per gestire eventuali eccezioni risultanti. Un blocco finally contiene codice che viene eseguito indipendentemente dal fatto che venga generata o meno un'eccezione nel blocco try
, come, ad esempio, il rilascio delle risorse allocate nel blocco try
. Un try
blocco richiede uno o più blocchi associati catch
o un finally
blocco o entrambi.
Negli esempi seguenti viene mostrata un'istruzione try-catch
, un'istruzione try-finally
e un'istruzione try-catch-finally
.
try
{
// Code to try goes here.
}
catch (SomeSpecificException ex)
{
// Code to handle the exception goes here.
// Only catch exceptions that 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 goes here.
}
finally
{
// Code to execute after the try block goes here.
}
try
{
// Code to try goes here.
}
catch (SomeSpecificException ex)
{
// Code to handle the exception goes here.
}
finally
{
// Code to execute after the try (and possibly catch) blocks
// goes here.
}
Un try
blocco senza un catch
blocco o un finally
blocco provoca un errore del compilatore.
Blocchi catch
Un catch
blocco può specificare il tipo di eccezione da intercettare. La specifica del tipo è denominata filtro eccezioni. Il tipo di eccezione deve essere derivato da Exception. In generale, non specificare Exception come filtro eccezioni, a meno che non si sappia come gestire tutte le eccezioni che potrebbero essere generate nel blocco try
, o se è stata inclusa una dichiarazione throw
alla fine del blocco catch
.
È possibile concatenare più catch
blocchi con classi di eccezione diverse. I catch
blocchi vengono valutati dall'alto verso il basso nel codice, ma viene eseguito un catch
solo blocco per ogni eccezione generata. Viene eseguito il primo catch
blocco che specifica il tipo esatto o una classe base dell'eccezione generata. Se nessun blocco catch
specifica una classe di eccezione corrispondente, viene selezionato un blocco catch
che non dispone di alcun tipo, se presente nella dichiarazione. È importante posizionare i blocchi catch
con le classi di eccezioni più specifiche (ovvero le classi di eccezioni più derivate).
Catturare le eccezioni quando le condizioni seguenti sono vere:
- Si ha una buona conoscenza del motivo per cui l'eccezione potrebbe essere generata e è possibile implementare un ripristino specifico, ad esempio richiedendo all'utente di immettere un nuovo nome di file quando si intercetta un FileNotFoundException oggetto.
- È possibile creare e generare una nuova eccezione più specifica.
int GetInt(int[] array, int index) { try { return array[index]; } catch (IndexOutOfRangeException e) { throw new ArgumentOutOfRangeException( "Parameter index is out of range.", e); } }
- Si vuole gestire parzialmente un'eccezione prima di passarla per una gestione più approfondita. Nell'esempio seguente viene usato un
catch
blocco per aggiungere una voce a un log degli errori prima di rigenerare l'eccezione.try { // Try to access a resource. } catch (UnauthorizedAccessException e) { // Call a custom error logging procedure. LogError(e); // Re-throw the error. throw; }
È anche possibile specificare filtri eccezioni per aggiungere un'espressione booleana a una clausola catch. I filtri eccezioni indicano che una clausola catch specifica venga soddisfatta solo quando tale condizione è vera. Nell'esempio seguente entrambe le clausole catch usano la stessa classe di eccezione, ma viene verificata una condizione aggiuntiva per creare un messaggio di errore diverso:
int GetInt(int[] array, int index)
{
try
{
return array[index];
}
catch (IndexOutOfRangeException e) when (index < 0)
{
throw new ArgumentOutOfRangeException(
"Parameter index cannot be negative.", e);
}
catch (IndexOutOfRangeException e)
{
throw new ArgumentOutOfRangeException(
"Parameter index cannot be greater than the array size.", e);
}
}
Un filtro eccezioni che restituisce false
sempre può essere usato per esaminare tutte le eccezioni, ma non elaborarle. Un uso tipico consiste nel registrare le eccezioni:
public class ExceptionFilter
{
public static void Main()
{
try
{
string? s = null;
Console.WriteLine(s.Length);
}
catch (Exception e) when (LogException(e))
{
}
Console.WriteLine("Exception must have been handled");
}
private static bool LogException(Exception e)
{
Console.WriteLine($"\tIn the log routine. Caught {e.GetType()}");
Console.WriteLine($"\tMessage: {e.Message}");
return false;
}
}
Il LogException
metodo restituisce sempre false
, nessuna catch
clausola corrisponde a questo filtro di eccezioni. La clausola catch può essere generale, usando System.Exceptione le clausole successive possono elaborare classi di eccezioni più specifiche.
Blocchi finally
Un finally
blocco consente di pulire le azioni eseguite in un try
blocco. Se presente, il finally
blocco viene eseguito per ultimo, dopo il try
blocco e qualsiasi blocco corrispondente catch
. Viene sempre eseguito un finally
blocco, indipendentemente dal fatto che venga generata un'eccezione o che venga trovato un catch
blocco corrispondente al tipo di eccezione.
Il finally
blocco può essere usato per rilasciare risorse come flussi di file, connessioni di database e handle grafici senza attendere che il Garbage Collector nel runtime finalizzi gli oggetti.
Nell'esempio seguente il finally
blocco viene usato per chiudere un file aperto nel try
blocco . Si noti che lo stato dell'handle di file viene controllato prima della chiusura del file. Se il try
blocco non riesce ad aprire il file, l'handle di file ha ancora il valore null
e il finally
blocco non tenta di chiuderlo. Se invece il file viene aperto correttamente nel try
blocco, il finally
blocco chiude il file aperto.
FileStream? file = null;
FileInfo fileinfo = new System.IO.FileInfo("./file.txt");
try
{
file = fileinfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// Check for null because OpenWrite might have failed.
file?.Close();
}
Specifiche del linguaggio C#
Per altre informazioni, vedere Eccezioni e Istruzione try nella specifica del linguaggio C#. La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.