try-catch (Référence C#)

Mise à jour : novembre 2007

L'instruction try-catch consiste en un bloc try suivi d'une ou de plusieurs clauses catch, qui désignent les gestionnaires des différentes exceptions. Quand une exception est levée, le Common Language Runtime (CLR) recherche l'instruction catch qui gère cette exception. Si la méthode en cours d'exécution ne contient pas de bloc catch, le CLR examine la méthode qui a appelé la méthode actuelle, et ainsi de suite en remontant la pile des appels. Si aucun bloc catch n'est trouvé, le CLR affiche un message d'exception non gérée destiné à l'utilisateur et arrête l'exécution du programme.

Le bloc try contient le code protégé risquant de provoquer l'exception. Le bloc est exécuté jusqu'à la levée d'une exception ou jusqu'à sa réussite totale. Par exemple, la tentative suivante d'opérer un cast sur un objet null déclenche l'exception NullReferenceException :

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

Bien que la clause catch puisse être employée sans arguments afin d'intercepter tout type d'exception, cette utilisation est déconseillée. En général, vous devez intercepter uniquement les exceptions que vous savez récupérer. Par conséquent, vous devez toujours spécifier un argument objet dérivé de System.Exception. Exemple :

catch (InvalidCastException e) 
{
}

Il est possible d'utiliser plus d'une clause catch spécifique dans la même instruction try-catch. Dans ce cas, l'ordre des clauses catch est important parce que les clauses catch sont examinées dans l'ordre. Interceptez les exceptions les plus spécifiques avant celles qui le sont le moins. Le compilateur génère une erreur si vous ordonnez vos blocs catch de sorte qu'un bloc ultérieur ne soit jamais atteint.

Une instruction throw peut être utilisée dans le bloc catch pour lever une nouvelle fois l'exception interceptée par l'instruction catch. Par exemple :

catch (InvalidCastException e) 
{
    throw (e);    // Rethrowing exception e
}

Vous pouvez également lever une nouvelle exception. Spécifiez alors l'exception interceptée en tant qu'exception interne :

catch (InvalidCastException e) 
{
   // Can do cleanup work here.
    throw new CustomException("Error message here.", e);
}

Si vous souhaitez lever une nouvelle fois l'exception actuellement gérée par une clause catch sans paramètres, utilisez l'instruction throw sans arguments. Par exemple :

catch
{
    throw;
}

Dans un bloc try, initialisez uniquement les variables qui y sont déclarées ; dans le cas contraire, une exception peut survenir avant la fin de l'exécution du bloc. Par exemple, dans l'exemple de code suivant, la variable x est initialisée dans le bloc try. Toute tentative d'utilisation de cette variable en dehors du bloc try dans l'instruction Write(x) générera l'erreur de compilation : Utilisation d'une variable locale non assignée.

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

Pour plus d'informations sur catch, consultez try-catch-finally.

Exemple

Dans cet exemple, le bloc try contient un appel à la méthode ProcessString qui peut provoquer une exception. La clause catch contient le gestionnaire d'exceptions qui affiche simplement un message à l'écran. Quand l'instruction throw est appelée de l'intérieur de MyMethod, le système recherche l'instruction catch et affiche le message 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.
     * */

Dans cet exemple, deux instructions catch sont utilisées. L'instruction la plus spécifique, qui apparaît la première, est interceptée.

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 TryFinallyTest.Main() First exception caught.
*/

Dans l'exemple précédent, si vous commencez par la clause catch la moins spécifique, vous obtiendrez le message d'erreur suivant : 

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

Cependant, pour intercepter l'exception la moins spécifique, remplacez l'expression throw par la suivante :

throw new Exception();

Spécification du langage C#

Pour plus d'informations, consultez les sections suivantes dans Spécifications du langage C#.

  • 5.3.3.13 Instructions try-catch

  • 8.10 L'instruction try

  • 16 Exceptions

Voir aussi

Tâches

Comment : lever explicitement des exceptions

Concepts

Guide de programmation C#

Référence

Mots clés C#

The try, catch, and throw Statements

Instructions de gestion des exceptions (Référence C#)

throw (Référence C#)

try-finally (Référence C#)

Autres ressources

Référence C#