try-catch (Riferimenti per C#)

L'istruzione try-catch è costituita da un blocco try seguito da una o più clausole catch che specificano gestori per diverse eccezioni. Quando viene generata un'eccezione, Common Language Runtime (CLR) cerca l'istruzione catch che gestisce l'eccezione indicata. Se il metodo in esecuzione non contiene tale blocco catch, CLR analizza il metodo che ha chiamato il metodo corrente e così via lungo lo stack di chiamate. Se non viene trovato alcun blocco catch, CLR visualizza un messaggio di eccezione non gestita all'utente e interrompe l'esecuzione del programma.

Il blocco try contiene il codice controllato che può generare l'eccezione. Il blocco viene eseguito fino a quando non viene generata un'eccezione o fino al corretto completamento dell'esecuzione. Ad esempio, il tentativo riportato di seguito di eseguire il cast di un oggetto null genera l'eccezione NullReferenceException:

object o2 = null;
try
{
    int i2 = (int)o2;   // Error
}

Anche se la clausola catch può essere utilizzata senza argomenti per rilevare qualsiasi tipo di eccezione, questo utilizzo non viene consigliato. In generale, è opportuno rilevare solo le eccezioni per le quali si conosce la modalità di recupero. Pertanto, è consigliabile specificare sempre un argomento oggetto derivato da System.Exception, ad esempio:

catch (InvalidCastException e) 
{
}

È possibile utilizzare più di una clausola catch specifica nella stessa istruzione try-catch. In questo caso, l'ordine delle clausole catch è importante poiché le clausole catch vengono esaminate nell'ordine specificato. Vengono intercettate prima le eccezioni più specifiche, quindi quelle meno specifiche. Il compilatore produce un errore se si ordinano i blocchi catch in modo tale da non poter raggiungere mai un blocco successivo.

Un'istruzione throw può essere utilizzata in un blocco catch per rigenerare l'eccezione intercettata dall'istruzione catch. Nel seguente esempio vengono estratte le informazioni di origine da un'eccezione IOException e quindi generata l'eccezione nel metodo padre.

catch (FileNotFoundException e)
{
    // FileNotFoundExceptions are handled here.
}
catch (IOException e)
{
    // Extract some information from this exception, and then 
    // throw it to the parent method.
    if (e.Source != null)
        Console.WriteLine("IOException source: {0}", e.Source);
    throw;
}

È possibile intercettare un'eccezione e generare un'eccezione diversa. In tal caso, specificare l'eccezione che è stata catturata come eccezione interna, come illustrato nell'esempio seguente.

catch (InvalidCastException e) 
{
    // Perform some action here, and then throw a new exception.
    throw new YourCustomException("Put your error message here.", e);
}

È inoltre possibile generare nuovamente un'eccezione quando una condizione specifica è vera, come illustrato nell'esempio seguente.

catch (InvalidCastException e)
{
    if (e.Data == null)
    {
        throw;
    }
    else
    {
        // Take some action.
    }
 }

All'interno di un blocco try, inizializzare solo le variabili che vengono dichiarate al suo interno. In caso contrario, un'eccezione può verificarsi prima del completamento dell'esecuzione del blocco. Nell'esempio di codice riportato di seguito, ad esempio, la variabile n viene inizializzata all'interno del blocco try. Un tentativo di utilizzare questa variabile all'esterno del blocco try nell'istruzione Write(n) genera un errore del compilatore.

static void Main() 
{
    int n;
    try 
    {
        // Do not initialize this variable here.
        n = 123;
    }
    catch
    {
    }
    // Error: Use of unassigned local variable 'n'.
    Console.Write(n);
}

Per ulteriori informazioni sulla clausola catch, vedere try-catch-finally.

Esempio

Negli esempi seguenti, il blocco try contiene una chiamata al metodo ProcessString che potrebbe causare un'eccezione. La clausola catch contiene il gestore eccezioni che consente semplicemente di visualizzare un messaggio sullo schermo. Quando l'istruzione throw viene chiamata dall'interno di MyMethod, il sistema cerca l'istruzione catch e visualizza il messaggio Exception caught.

    class TryFinallyTest
{
    static void ProcessString(string s)
    {
        if (s == null)
        {
            throw new ArgumentNullException();
        }
    }

    static void Main()
    {
        string s = null; // For demonstration purposes.

        try
        {            
            ProcessString(s);
        }

        catch (Exception e)
        {
            Console.WriteLine("{0} Exception caught.", e);
        }
    }
}
    /*
    Output:
    System.ArgumentNullException: Value cannot be null.
       at TryFinallyTest.Main() Exception caught.
     * */

In questo esempio vengono utilizzate due istruzioni catch. Viene intercettata l'eccezione più specifica, che è la prima nell'ordine.

class ThrowTest3
{
    static void ProcessString(string s)
    {
        if (s == null)
        {
            throw new ArgumentNullException();
        }
    }

    static void Main()
    {
        try
        {
            string s = null;
            ProcessString(s);
        }
        // Most specific:
        catch (ArgumentNullException e)
        {
            Console.WriteLine("{0} First exception caught.", e);
        }
        // Least specific:
        catch (Exception e)
        {
            Console.WriteLine("{0} Second exception caught.", e);
        }
    }
}
/*
 Output:
 System.ArgumentNullException: Value cannot be null.
 at Test.ThrowTest3.ProcessString(String s) ... First exception caught.
*/

Nell'esempio precedente, se si inizia con la clausola catch meno specifica, verrà generato il seguente messaggio di errore:

A previous catch clause already catches all exceptions of this or a super type ('System.Exception')

Per rilevare l'eccezione meno specifica, è necessario sostituire l'istruzione throw con l'istruzione seguente:

throw new Exception();

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

Attività

Procedura: generare eccezioni in modo esplicito

Riferimenti

Parole chiave di C#

try, catch, and throw Statements (C++)

Istruzioni di gestione delle eccezioni (Riferimenti per C#)

throw (Riferimenti per C#)

try...finally (Riferimenti per C#)

Concetti

Guida per programmatori C#

Altre risorse

Riferimenti per C#

Cronologia delle modifiche

Data

Cronologia

Motivo

Luglio 2010

Aggiornamento degli esempi throw.

Commenti e suggerimenti dei clienti.