Gestion des erreurs en C# : try/catch et plus encore
La gestion des erreurs est l'un des composants clés d'un logiciel fiable. En C#, le mécanisme des exceptions est utilisé à cette fin. L'utilisation judicieuse des constructions try, catch et finally permet non seulement d'éviter l'arrêt brutal du programme, mais aussi de rendre le code plus lisible et prévisible. Dans cet article, nous aborderons les bases de la gestion des exceptions, les meilleures pratiques et les fonctionnalités avancées offertes par la plateforme .NET.
1. Bloc de base try/catch/finally
L'outil principal de gestion des erreurs en C# est le bloc try-catch-finally. Sa syntaxe est intuitive :
- try — contient le code qui peut lever une exception.
- catch — intercepte et traite l'exception.
- finally — s'exécute toujours, qu'une exception ait eu lieu ou non. Il est utilisé pour libérer les ressources (fermeture de fichiers, connexions à la base de données).
Prenons un exemple simple — la division par zéro :
using System;
class Program{ static void Main() { try { int a = 10; int b = 0; int result = a / b; // Une exception se produira ici Console.WriteLine($"Résultat : {result}"); } catch (DivideByZeroException ex) { Console.WriteLine($"Erreur : {ex.Message}"); } finally { Console.WriteLine("Bloc finally exécuté."); } }}Sortie du programme :
Erreur : Tentative de division par zéro.Bloc finally exécuté.Notez que si vous ne spécifiez pas de type d'exception concret, le bloc catch interceptera toutes les exceptions. Cela peut être pratique, mais est souvent considéré comme une mauvaise pratique car cela masque les problèmes réels.
2. Types d'exceptions et leur hiérarchie
En C#, toutes les exceptions héritent de la classe de base System.Exception. Les plus couramment utilisées sont :
SystemException— classe de base pour les exceptions système.NullReferenceException— accès à un objet qui estnull.IndexOutOfRangeException— dépassement des limites d'un tableau.InvalidOperationException— appel d'une méthode dans un état non valide.ArgumentExceptionet ses descendants (ArgumentNullException,ArgumentOutOfRangeException) — arguments de méthode incorrects.
Vous pouvez intercepter plusieurs types d'exceptions dans un seul bloc catch (à partir de C# 6) :
try{ // code}catch (ArgumentNullException ex) when (ex.ParamName == "userId"){ Console.WriteLine("Le paramètre userId ne doit pas être null.");}catch (InvalidOperationException ex){ Console.WriteLine($"Opération incorrecte : {ex.Message}");}catch (Exception ex) when (Log(ex, "Erreur inconnue")){ // Filtre d'exception — le bloc s'exécute uniquement si la condition est vraie throw; // Relance l'exception plus loin}Les filtres d'exception (mot-clé when) permettent de gérer la logique de traitement de manière plus flexible, sans perdre la pile d'appels.
3. Génération de vos propres exceptions
Parfois, les exceptions standard ne suffisent pas. Vous pouvez créer votre propre classe d'exception en héritant de Exception :
public class InvalidAgeException : Exception{ public int Age { get; }
public InvalidAgeException(int age, string message) : base(message) { Age = age; }
public InvalidAgeException(int age, string message, Exception inner) : base(message, inner) { Age = age; }}Maintenant