Gestione delle eccezioni (Guida per programmatori C#)

Un blocco try viene utilizzato dai programmatori C# per partizionare il codice in cui potrebbe essere rilevata un'eccezione. I blocchi catch associati vengono utilizzati per gestire tutte le eccezioni risultanti. Un blocco finally contiene il codice eseguito indipendentemente dal fatto che venga generata o meno un'eccezione nel blocco try, come ad esempio le risorse di rilascio allocate nel blocco try. Un blocco try richiede uno o più blocchi catch associati, un blocco finally o entrambi.

Negli esempi seguenti vengono illustrate 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 blocco try senza un blocco catch o finally genera un errore del compilatore.

Blocchi catch

Un blocco catch consente di specificare il tipo di eccezione da intercettare. La specifica del tipo è chiamata filtro eccezioni. Il tipo di eccezione deve essere derivato da Exception. In genere, non specificare Exception come filtro di eccezione a meno che non si sa come gestire tutte le eccezioni che potrebbero essere generate nel blocco try o non si è inclusa un'istruzione throw alla fine del blocco catch.

È possibile concatenare più blocchi catch con filtri eccezioni differenti. I blocchi catch vengono valutati dall'alto verso il basso nel codice, 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, un blocco catch che non dispone di filtro viene selezionato, se presente nell'istruzione. È importante posizionare per primi i blocchi catch con i tipi di eccezioni più specifici (ossia più derivati).

È necessario intercettare le eccezioni quando le condizioni seguenti sono vere:

  • Si dispone di buone informazioni sul motivo per cui potrebbe essere stata generata l'eccezione ed è possibile implementare un recupero specifico, come richiedere all'utente di immettere un nuovo nome di file quando si intercetta un oggetto FileNotFoundException.

  • È possibile creare e generare una nuova eccezione più specifica.

    int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch(System.IndexOutOfRangeException e)
        {
            throw new System.ArgumentOutOfRangeException(
                "Parameter index is out of range.");
        }
    }
    
  • Si desidera gestire parzialmente un'eccezione prima di passarla per la gestione aggiuntiva. Nell'esempio seguente, un blocco catch viene utilizzato per aggiungere una voce al log degli errori prima di ri-generare l'eccezione.

    try
    {
        // Try to access a resource.
    }
    catch (System.UnauthorizedAccessException e)
    {
        // Call a custom error logging procedure.
        LogError(e);
        // Re-throw the error.
        throw;     
    }
    

Blocchi finally

Un blocco finally consente la pulizia delle azioni eseguite in un blocco try. Se presente, il blocco finally viene eseguito per ultimo, dopo il blocco try e il rispettivo 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 al blocco try non è possibile aprire il file, l'handle di file ha sempre il valore null e il blocco finally non tenta di chiuderlo. In alternativa, se il file è aperto correttamente nel blocco try, il blocco finally chiude 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 la Specifiche del linguaggio C#. La specifica del linguaggio è la fonte ufficiale per la sintassi e l'utilizzo di C#.

Vedere anche

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#)

Istruzione using (Riferimenti per C#)

Concetti

Guida per programmatori C#

Altre risorse

Riferimenti per C#