FAQ C#Consultez toutes les FAQ

Nombre d'auteurs : 39, nombre de questions : 272, dernière mise à jour : 24 mai 2015  Ajouter une question

 

Cette FAQ a été réalisée pour répondre aux questions les plus fréquemment posées concernant C# sur le forum Développement DotNET

Je tiens à souligner qu'elle ne garantit en aucun cas que les informations qu'elle contient sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Si vous trouvez une erreur, ou que vous souhaitez devenir rédacteur, lisez ceci .

Sur ce, je vous souhaite une bonne lecture.

Commentez cette FAQ : Commentez


SommaireLe langage C#Gestion d'erreurs (5)
précédent sommaire suivant
 

Pour intercepter un exception (erreur) qui se produit dans le code, il faut placer le code « à risque » dans un bloc try/catch. Quand une instruction du bloc try provoque une exception, l'exécution saute au prochain bloc catch qui correspond, puis l'exécution reprend à la suite du try/catch. Si aucun bloc catch ne correspond à l'exception levée, celle-ci remonte la pile des appels jusqu'à ce qu'elle soit interceptée par un bloc try/catch... ou jusqu'au plantage du programme si elle n'est jamais interceptée.

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
try 
{ 
    AttentionCaPeutPlanter(); 
    Console.WriteLine("Si on est arrivé jusqu'ici, c'est que tout s'est bien passé..."); 
} 
catch(Exception ex) 
{ 
    // Ce code n'est exécuté que si une exception se produit 
    Console.WriteLine("Une erreur s'est produite : {0}", ex.Message); 
}
On indique en paramètre de catch le type de l'exception à intercepter. Exception étant la classe de base de toutes les exceptions, le code catch(Exception) interceptera toutes les erreurs (sauf quelques-unes qui ne peuvent pas être interceptées). Il est généralement recommandé de n'intercepter que les erreurs qu'on est capable de gérer, il vaut donc mieux intercepter des exceptions d'un type spécifique.
On peut également intercepter plusieurs types d'exceptions différents, de la façon suivante :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
try 
{ 
    OperationSurUnFichier(); 
    Console.WriteLine("OK, traitement terminé"); 
} 
catch(IOException ex) 
{ 
    Console.WriteLine("Une erreur d'entrée/sortie s'est produite : {0}", ex.Message); 
} 
catch(UnauthorizedAccessException ex) 
{ 
    Console.WriteLine("L'accès a été refusé : {0}", ex.Message); 
} 
catch(Exception ex) 
{ 
    // Toutes les exceptions non interceptées par les deux premiers catch sont interceptées par celui-ci 
    Console.WriteLine("Une erreur s'est produite : {0}", ex.Message); 
}

Mis à jour le 8 mars 2010 tomlev

Un bloc try peut être complété par un bloc finally. Le contenu de ce bloc sera exécuté quoi qu'il arrive, même si une exception se produit. Dans ce dernier cas, le bloc catch (s'il existe) est exécuté, plus le bloc finally, puis l'exception remonte la pile si elle n'a pas été interceptée par un bloc catch (ou si elle a été relancée). Le bloc finally est particulièrement utile pour effectuer du code de « nettoyage » avant de quitter la méthode en cours.

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public string LireLaPremiereLigneSiLeFichierExiste() 
{ 
    StreamReader reader = null; 
    try 
    { 
        reader = new StreamReader("MonFichier.txt"); 
        string line = reader.ReadLine(); 
        return line; 
    } 
    catch(FileNotFoundException ex) 
    { 
        // Le fichier n'existe pas, on renvoie null 
        return null; 
    } 
    finally 
    { 
    	  // Quoiqu'il arrive, on ferme le fichier avant de quitter la méthode 
        if (reader != null) 
            reader.Close(); 
    } 
}
Dans ce code, remarquez que, bien que le return se situe avant le bloc finally, ce dernier est quand même toujours exécuté avant de quitter la méthode. Notez aussi qu'il n'est pas obligatoire d'écrire un bloc catch : on peut écrire simplement un bloc try/finally si on a pas besoin de gérer l'erreur.

Mis à jour le 8 mars 2010 tomlev

Il est possible d'intercepter une exception pour l'examiner, l'écrire dans un log, etc., puis de la "relancer" pour la laisser remonter la pile d'appel jusqu'au prochain bloc try/catch. Pour cela, on utilise le mot-clé throw, sans spécifier de paramètre :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
  
try 
{ 
    AttentionCaPeutPlanter(); 
} 
catch(Exception ex) 
{ 
    Console.WriteLine("Oups, une erreur s'est produite : {0}", ex.Message); 
  
    // On laisse l'erreur remonter 
    throw; 
}
Il est très important d'utiliser l'instruction throw et non throw ex : en effet, throw ex réinitialise les informations sur la pile d'appels contenues dans l'exception, ce qui empêche de déterminer avec précision l'origine de l'erreur initiale.
Il est également possible « d'enrichir » une exception pour lui ajouter des informations. Il faut dans ce cas lancer une nouvelle exception qui "englobe" celle qu'on a interceptée :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
  
try 
{ 
    AttentionCaPeutPlanter(); 
} 
catch(Exception ex) 
{ 
    // On enrichit l'erreur d'un message personnalisé, et on la relance 
    throw new Exception("Aie, l'appel à AttentionCaPeutPlanter à planter... voir l'erreur interne pour les détails", ex); 
}
L'exception ainsi englobée est accessible via la propriété InnerException de l'exception qu'on a relancée.

Mis à jour le 8 mars 2010 tomlev

Si votre code reçoit un argument incorrect, se trouve dans une situation invalide, etc., vous pouvez le signaler en levant une exception grâce au mot-clé throw. Par exemple, la méthode suivante lève une exception de type ArgumentNullException si le paramètre nom est null :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
public void DisBonjour(string nom) 
{ 
    if (nom == null) 
        throw new ArgumentNullException("nom", "Le nom n'est pas spécifié"); 
  
    Console.WriteLine("Bonjour {0}", nom); 
}

Mis à jour le 8 mars 2010 tomlev

Toute exception dérive de la classe Exception. Pour créer une exception personnalisée, il faut donc créer une nouvelle classe dérivée de la classe Exception.
Il est également conseillé de fournir un constructeur qui permet de définir l'exception interne, afin de fournir plus d'informations sur l'exception.

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MonException : Exception 
{ 
    public MonException() 
        : base("Exception personnalisée") 
    { } 
  
    public MonException(string message) 
        : base("Exception personnalisée : " + message) 
    { } 
  
    public MonException(string message, Exception innerException) 
        : base("Exception personnalisée : " + message, innerException) 
    { } 
}
Dans la première version de .NET, il était recommandé de créer les exceptions personnalisées en héritant de la classe ApplicationException, afin de pouvoir distinguer les exceptions de l'application de celles du .NET Framework. Etant donné que certaines exceptions du framework ne respectaient pas cette recommandation, cette recommandation a été supprimée car n'a plus de sens (voir l'article de Krzysztof Cwalina à ce sujet, ainsi que le lien ci-dessous).

Mis à jour le 25 mars 2007 Jérôme Lambert tomlev

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsable bénévole de la rubrique Microsoft DotNET : Hinault Romaric -