CA2202 : Ne pas supprimer d'objets plusieurs fois

Élément Valeur
ID de la règle CA2202
Category Microsoft.Usage
Modification avec rupture Sans rupture

Cause

Une implémentation de méthode contient des chemins d’accès de code qui peuvent provoquer des appels multiples à System.IDisposable.Dispose ou un Dispose équivalent, par exemple, une méthode Close() sur certains types, sur le même objet.

Notes

Cette règle est déconseillée. Pour plus d’informations, consultez Règles dépréciées.

Description de la règle

Une méthode Dispose correctement implémentée peut être appelée plusieurs fois sans lever d’exception. Toutefois, cela n’est pas garanti, et pour éviter de générer une System.ObjectDisposedException, vous ne devez pas appeler Dispose plusieurs fois sur un objet.

Comment corriger les violations

Pour corriger une violation de cette règle, modifiez l’implémentation de sorte que, quel que soit le chemin du code, Dispose ne soit appelé qu’une seule fois pour l’objet.

Quand supprimer les avertissements

Ne supprimez aucun avertissement de cette règle. Même si Dispose pour l’objet est connu pour être appelable en toute sécurité plusieurs fois, l’implémentation peut changer à l’avenir.

Exemple 1

Les instructions using imbriquées (Using en Visual Basic) peuvent provoquer des violations de l’avertissement CA2202. Si la ressource IDisposable de l’instruction using interne imbriquée contient la ressource de l’instruction externe using, la méthode Dispose de la ressource imbriquée libère la ressource contenue. Lorsque cette situation se produit, la méthode Dispose de l’instruction using externe tente de supprimer sa ressource pour une deuxième fois.

Dans l’exemple suivant, un objet Stream créé dans une instruction using externe est publié à la fin de l’instruction using interne dans la méthode Dispose de l’objet StreamWriter qui contient l’objet stream. À la fin de l’instruction using externe, l’objet stream est libéré une deuxième fois. La deuxième version est une violation de CA2202.

using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
    using (StreamWriter writer = new StreamWriter(stream))
    {
        // Use the writer object...
    }
}

Exemple 2

Pour résoudre ce problème, utilisez un bloc try/finally au lieu de l’instruction using externe. Dans le bloc finally, vérifiez que la ressource stream n’est pas null.

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    stream?.Dispose();
}

Conseil

La syntaxe ?. ci-dessus est l’opérateur conditionnel null.

Voir aussi