CA1063 : Implémenter IDisposable correctementCA1063: Implement IDisposable correctly

TypeNameTypeName ImplementIDisposableCorrectlyImplementIDisposableCorrectly
CheckIdCheckId CA1063CA1063
CategoryCategory Microsoft.DesignMicrosoft.Design
Modification avec ruptureBreaking Change Sans ruptureNon-breaking

CauseCause

IDisposable n’est pas implémentée correctement.IDisposable is not implemented correctly. Voici quelques raisons pour lesquelles ce problème :Some reasons for this problem are listed here:

  • IDisposable est réimplémenté dans la classe.IDisposable is re-implemented in the class.

  • Finalize est substitué à nouveau.Finalize is re-overridden.

  • Dispose est substitué.Dispose is overridden.

  • Dispose() n’est pas public, scellé ni Dispose nommé.Dispose() is not public, sealed, or named Dispose.

  • Dispose (bool) n’est pas protégé, virtuel ou non scellé.Dispose(bool) is not protected, virtual, or unsealed.

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

  • Pour les types déverrouillés, l’implémentation Finalize n’appelle pas le finaliseur de classe de cas ou de dispose (bool) un ou les deux.For unsealed types, the Finalize implementation does not call either or both Dispose(bool) or the case class finalizer.

Violation de l’un de ces modèles déclenche cet avertissement.Violation of any one of these patterns will trigger this warning.

Chaque type unsealed qui déclare et implémente l’interface IDisposable doit fournir sa propre méthode Dispose (bool) void virtuelle protégée.Every unsealed type that declares and implements the IDisposable interface must provide its own protected virtual void Dispose(bool) method. Dispose() doit appeler Dipose (true) et Finalize doit appeler Dispose (false).Dispose() should call Dipose(true) and Finalize should call Dispose(false). Si vous créez un type unsealed qui déclare et implémente l’interface IDisposable, vous devez définir dispose (bool) et l’appeler.If you are creating an unsealed type that declares and implements the IDisposable interface, you must define Dispose(bool) and call it. Pour plus d’informations, consultez nettoyage des ressources non managées dans les les règles de conception de .NET Framework.For more information, see Cleaning up unmanaged resources in the .NET Framework design guidelines.

Description de la règleRule description

Tous les types IDisposable doivent implémenter le modèle Dispose correctement.All IDisposable types should implement the Dispose pattern correctly.

Comment corriger les violationsHow to fix violations

Examinez votre code et déterminer lequel des solutions suivantes corrigera cette violation.Examine your code and determine which of the following resolutions will fix this violation.

  • Supprimez IDisposable de la liste des interfaces qui est implémentée par {0} et substituer l’implémentation de Dispose de la classe de base à la place.Remove IDisposable from the list of interfaces that are implemented by {0} and override the base class Dispose implementation instead.

  • Supprimez le finaliseur du type {0}, substituez Dispose (bool disposing) et placez la logique de finalisation dans le chemin d’accès du code où 'disposing' a la valeur false.Remove the finalizer from type {0}, override Dispose(bool disposing), and put the finalization logic in the code path where 'disposing' is false.

  • Supprimez {0}, substituez Dispose (bool disposing) et placez la logique dispose dans le chemin d’accès du code où 'disposing' a la valeur true.Remove {0}, override Dispose(bool disposing), and put the dispose logic in the code path where 'disposing' is true.

  • Vérifiez que {0} est déclaré comme public et sealed.Ensure that {0} is declared as public and sealed.

  • Renommer {0} en 'Dispose' et vérifiez qu’il est déclaré comme public et sealed.Rename {0} to 'Dispose' and make sure that it is declared as public and sealed.

  • Assurez-vous que {0} est déclaré comme protected, virtual et unsealed.Make sure that {0} is declared as protected, virtual, and unsealed.

  • Modifiez {0} afin qu’il appelle Dispose (true), puis appelle GC. SuppressFinalize sur l’instance d’objet actuelle ('this' ou 'Me' dans Visual BasicVisual Basic), puis retourne.Modify {0} so that it calls Dispose(true), then calls GC.SuppressFinalize on the current object instance ('this' or 'Me' in Visual BasicVisual Basic), and then returns.

  • Modifiez {0} afin qu’il appelle Dispose (false), puis retourne.Modify {0} so that it calls Dispose(false) and then returns.

  • Si vous créez un type unsealed qui déclare et implémente l’interface IDisposable, assurez-vous que l’implémentation de IDisposable suit le modèle qui est décrite plus haut dans cette section.If you are creating an unsealed type that declares and implements the IDisposable interface, make sure that the implementation of IDisposable follows the pattern that is described earlier in this section.

Quand supprimer les avertissementsWhen to suppress warnings

Ne supprimez aucun avertissement de cette règle.Do not suppress a warning from this rule.

Exemple de pseudo-codePseudo-code example

Le pseudo-code suivant fournit un exemple général de la manière dont dispose (bool) doit être implémentée dans une classe qui utilise gérée et ressources natives.The following pseudo-code provides a general example of how Dispose(bool) should be implemented in a class that uses managed and native resources.

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