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 (garbage collector) ne peut pas nettoyer automatiquement - descripteurs de fichiers, connexions à des bases de données, sockets réseau. L'interface IDisposable fournit un moyen standard de libérer ces ressources lorsque vous avez fini de les utiliser.

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;
        }
    }
}

Vous pourriez appeler Dispose() manuellement, mais que se passe-t-il si une exception survient avant d'atteindre cette ligne ? L'instruction using garantit que le nettoyage est effectué, même quand les choses tournent mal :

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

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

void ProcessFile()
{
    using FileHandler handler = new FileHandler();
    // Travailler avec handler
}  // Dispose() est appelé à la sortie de la méthode

L'instruction using fonctionne avec n'importe quel 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 appropriée 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 l'ouverture et la fermeture des connexions, garantissant que les ressources sont 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 :
    • Avoir une propriété ConnectionName (chaîne de caractères, en lecture seule) définie via le constructeur
    • Suivre si la connexion a été libérée à l'aide d'un champ booléen privé
    • Afficher Connection opened: {ConnectionName} lors de la création de l'objet (dans le constructeur)
    • Implémenter la méthode Dispose() pour afficher Connection closed: {ConnectionName} - mais seulement si elle n'a pas déjà été libérée (pour éviter une double libération)
    • Avoir 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() sera appelé automatiquement.

Par exemple, si les entrées sont MainDB et SELECT * FROM Users, la sortie devrait ê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 vous rappeler d'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 !

Aide-mémoire

L'interface IDisposable fournit un moyen standard de libérer les ressources que le ramasse-miettes (garbage collector) ne peut pas nettoyer automatiquement (descripteurs de fichiers, connexions à des bases de données, sockets réseau).

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;
        }
    }
}

L'instruction using garantit que le nettoyage s'effectue automatiquement, même en cas d'exceptions :

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

Le C# moderne offre une syntaxe plus propre avec la déclaration using :

void ProcessFile()
{
    using FileHandler handler = new FileHandler();
    // Travailler avec le gestionnaire
}  // Dispose() est appelé à la sortie de la méthode

L'instruction using fonctionne avec n'importe quel type implémentant IDisposable, y compris les classes intégrées comme StreamReader, SqlConnection et HttpClient.

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: Utiliser une instruction 'using' pour créer une DatabaseConnection
        // À l'intérieur du bloc using :
        // 1. Appeler la méthode Query avec le sqlQuery
        // 2. Afficher le résultat de la méthode Query
        // La méthode Dispose sera appelée automatiquement à la fin du bloc using
        
    }
}
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