Nous recommandons d’utiliser Visual Studio 2017

CA1063 : Implémenter IDisposable correctement

 

Pour obtenir la dernière documentation sur Visual Studio 2017, consultez Documentation Visual Studio 2017.

TypeNameImplementIDisposableCorrectly
CheckIdCA1063
CatégorieMicrosoft.CSharp
Modification avec ruptureModification sans rupture

IDisposable n'est pas correctement implémentée. Voici quelques-unes des raisons de ce problème :

  • IDisposable est réimplémenté dans la classe.

  • Finalize est substitué à nouveau.

  • Dispose est substitué.

  • Dispose() n'est pas public, scellé ni Dispose nommé.

  • Dispose(bool) n'est pas protégé, virtuel ou non scellé.

  • Dans les types non scellés, Dispose() doit appeler Dispose(true).

  • Pour les types non scellés, l'implémentation Finalize n'appelle pas Dispose(bool), ni le finaliseur de classe case, ni les deux.

La violation de l'un de ces cas déclenche cet avertissement.

Chaque type IDisposable racine non scellé doit fournir sa propre méthode Dispose(bool) void virtuelle protégée. Dispose() doit appeler Dipose(true) et Finalize doit appeler Dispose(false). Si vous créez un type IDisposable racine non scellé, vous devez définir Dispose(bool) et l'appeler. Pour plus d'informations, consultez Cleaning Up Unmanaged Resources dans la section Instructions de conception d’infrastructure de la documentation du .NET Framework.

Tous les types IDisposable doivent implémenter le modèle Dispose correctement.

Examinez votre code et déterminez laquelle des solutions suivantes corrigera cette violation.

  • Supprimez IDisposable de la liste des interfaces implémentées par {0} et substituez l'implémentation Dispose de la classe de base.

  • Supprimez le finaliseur du type {0}, substituez Dispose(bool disposing) et placez la logique de finalisation dans le chemin du code où 'disposing' a la valeur False.

  • Supprimez {0}, substituez Dispose(bool disposing) et placez la logique dispose dans le chemin du code où 'disposing' a la valeur True.

  • Assurez-vous que {0} est déclaré comme public et sealed.

  • Renommez {0} en 'Dispose' et vérifiez qu'il est déclaré comme public et sealed.

  • Vérifiez que {0} est déclaré comme protected, virtual et unsealed.

  • Modifiez {0} afin qu'il appelle Dispose(true) et GC.SuppressFinalize sur l'instance de l'objet en cours ('this' ou 'Me' en Visual Basic) puis qu'il retourne une valeur.

  • Modifiez {0} afin qu'il appelle Dispose(false) et qu'il retourne une valeur.

  • Si vous écrivez une classe racine unsealed IDisposable, assurez-vous que l'implémentation IDisposable suit le modèle décrit plus tôt dans cette section.

Ne supprimez aucun avertissement de cette règle.

Le pseudo-code suivant fournit un exemple général de la manière dont Dispose(bool) doit être implémenté dans une classe qui utilise les ressources managées et natives.

public class Resource : IDisposable   
{  
    private IntPtr nativeResource = Marshal.AllocHGlobal(100);  
    private AnotherResource managedResource = new AnotherResource();  
  
// Dispose() calls Dispose(true)  
    public void Dispose()  
    {  
        Dispose(true);  
        GC.SuppressFinalize(this);  
    }  
    // NOTE: Leave out the finalizer altogether if this class doesn't   
    // own unmanaged resources itself, but leave the other methods  
    // exactly as they are.   
    ~Resource()   
    {  
        // Finalizer calls Dispose(false)  
        Dispose(false);  
    }  
    // The bulk of the clean-up code is implemented in Dispose(bool)  
    protected virtual void Dispose(bool disposing)  
    {  
        if (disposing)   
        {  
            // free managed resources  
            if (managedResource != null)  
            {  
                managedResource.Dispose();  
                managedResource = null;  
            }  
        }  
        // free native resources if there are any.  
        if (nativeResource != IntPtr.Zero)   
        {  
            Marshal.FreeHGlobal(nativeResource);  
            nativeResource = IntPtr.Zero;  
        }  
    }  
}  

Afficher: