Menu
Coddy logo textTech

IDisposable et l'instruction using

Fait partie de la section Programmation Orientée Objet du Journey C# de Coddy. Leçon 45 sur 70.

Certains objets conservent des ressources que le ramasse-miettes ne peut pas nettoyer automatiquement : des descripteurs de fichiers, des connexions à la base de données, des sockets réseau. L’interface IDisposable fournit un moyen standard de libérer ces ressources lorsque vous n’en avez plus besoin.

Une classe implémente IDisposable en fournissant une méthode Dispose() :

public class FileHandler : IDisposable
{
    private bool disposed = false;
    
    public void Dispose()
    {
        if (!disposed)
        {
            Console.WriteLine("Releasing resources...");
            disposed = true;
        }
    }
}

Tu pourrais appeler Dispose() manuellement, mais que se passe-t-il si une exception se produit avant que tu n’atteignes cette ligne ? L’instruction using garantit que le nettoyage a lieu, même lorsque les choses tournent mal :

using (FileHandler handler = new FileHandler())
{
    // Travailler avec le handler
}  // Dispose() appelé automatiquement ici

Le C# moderne offre une syntaxe plus claire avec la déclaration using, qui libère l’objet lorsqu’il sort de sa portée :

void ProcessFile()
{
    using FileHandler handler = new FileHandler();
    // Travailler avec handler
}  // Dispose() appelé lorsque la méthode se termine

L’instruction using fonctionne avec tout type qui implémente IDisposable. Les classes intégrées comme StreamReader, SqlConnection et HttpClient implémentent toutes cette interface, ce qui rend la gestion correcte des ressources simple et fiable.

challenge icon

Défi

Facile

Construisons un simulateur de connexion à une base de données qui démontre une gestion appropriée des ressources à l’aide de l’interface IDisposable et de l’instruction using. Vous allez créer une classe qui suit le moment où les connexions sont ouvertes et fermées, en veillant à ce que les ressources soient toujours correctement libérées.

Vous organiserez votre code sur deux fichiers :

  • DatabaseConnection.cs : créez une classe DatabaseConnection dans l’espace de noms DataAccess qui implémente IDisposable. Votre connexion doit :
    • posséder une propriété ConnectionName (de type string, en lecture seule) définie par le constructeur
    • suivre l’état d’élimination de la connexion à l’aide d’un champ booléen privé
    • afficher Connection opened: {ConnectionName} lorsque l’objet est créé (dans le constructeur)
    • implémenter la méthode Dispose() pour afficher Connection closed: {ConnectionName} — mais uniquement si elle n’a pas déjà été éliminée (afin d’éviter une double élimination)
    • posséder une méthode Query(string sql) qui retourne Executing on {ConnectionName}: {sql}
  • Program.cs : dans votre fichier principal, démontrez une gestion appropriée des ressources en utilisant l’instruction using avec votre connexion à la base de données. Créez une connexion, exécutez une requête et laissez le bloc using gérer automatiquement le nettoyage.

Vous recevrez deux entrées :

  • le nom de la connexion (par exemple, MainDB)
  • la requête SQL à exécuter (par exemple, SELECT * FROM Users)

Utilisez une instruction using pour créer votre connexion. À l’intérieur du bloc, appelez la méthode Query et affichez son résultat. Lorsque le bloc using se termine, Dispose() est appelée automatiquement.

Par exemple, si les entrées sont MainDB et SELECT * FROM Users, la sortie doit être :

Connection opened: MainDB
Executing on MainDB: SELECT * FROM Users
Connection closed: MainDB

Remarquez comment la connexion est automatiquement fermée lorsque le bloc using se termine : vous n’avez jamais besoin de penser à appeler Dispose() manuellement. Ce modèle garantit que les ressources sont toujours nettoyées, même si une exception se produit à l’intérieur du bloc !

Essayez vous-même

using System;
using DataAccess;

class Program
{
    public static void Main(string[] args)
    {
        string connectionName = Console.ReadLine();
        string sqlQuery = Console.ReadLine();
        
        // TODO: Utilisez une instruction 'using' pour créer une DatabaseConnection
        // À l'intérieur du bloc using :
        // 1. Appelez la méthode Query avec le sqlQuery
        // 2. Affichez le résultat de la méthode Query
        // La méthode Dispose sera appelée automatiquement lorsque le bloc using se termine
        
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur C# en ligne