CA1049 : Les types qui possèdent des ressources natives doivent être supprimables

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

Cause

Un type référence un champ System.IntPtr, System.UIntPtr ou System.Runtime.InteropServices.HandleRef, mais n’implémente pas System.IDisposable.

Description de la règle

Cette règle suppose que les champs IntPtr, UIntPtr et HandleRef stockent des pointeurs vers des ressources non managées. Les types qui allouent des ressources non managées doivent implémenter IDisposable pour permettre aux appelants de libérer ces ressources à la demande, et de raccourcir la durée de vie des objets qui contiennent les ressources.

Le modèle de conception recommandé pour nettoyer les ressources non managées consiste à fournir un moyen implicite et explicite de libérer ces ressources à l’aide de la méthode System.Object.Finalize et de la méthode System.IDisposable.Dispose, respectivement. Le récupérateur de mémoire appelle la méthode Finalize d’un objet à un moment indéterminé, une fois que l’objet n’est plus accessible. Une fois Finalize appelé, un nettoyage de la mémoire (garbage collection) supplémentaire est nécessaire pour libérer l’objet. La méthode Dispose permet à l’appelant de libérer explicitement les ressources à la demande, avant que les ressources ne soient libérées si elles sont laissées au récupérateur de mémoire. Une fois qu’il a nettoyé les ressources non managées, Dispose doit appeler la méthode System.GC.SuppressFinalize pour indiquer au récupérateur de mémoire que Finalize n’a plus besoin d’être appelé. Cela évite un nettoyage de la mémoire (garbage collection) supplémentaire, et raccourcit la durée de vie de l’objet.

Comment corriger les violations

Pour corriger toute violation de cette règle, implémentez IDisposable.

Quand supprimer les avertissements

Vous pouvez supprimer sans risque un avertissement lié à cette règle, si le type ne référence pas une ressource non managée. Sinon, ne supprimez pas l’avertissement lié à cette règle, car l’échec de l’implémentation de IDisposable peut entraîner l’indisponibilité ou la sous-utilisation des ressources non managées.

Exemple

L’exemple suivant montre un type qui implémente IDisposable pour nettoyer une ressource non managée.

using System;

namespace DesignLibrary
{
    public class UnmanagedResources : IDisposable
    {
        IntPtr unmanagedResource;
        bool disposed = false;

        public UnmanagedResources() 
        {
            // Allocate the unmanaged resource ...
        }

        public void Dispose() 
        {
            Dispose(true);
            GC.SuppressFinalize(this); 
        }

        protected virtual void Dispose(bool disposing)
        {
            if(!disposed)
            {
                if(disposing)
                {
                    // Release managed resources.
                }

                // Free the unmanaged resource ...

                unmanagedResource = IntPtr.Zero;

                disposed = true;
            }
        }

        ~UnmanagedResources()
        {
            Dispose(false);
        }
    }
}

CA2115 : Appelez GC.KeepAlive lorsque vous utilisez des ressources natives

CA1816 : Appeler GC.SuppressFinalize correctement

CA2216 : Les types pouvant être supprimés doivent déclarer un finaliseur

CA1001 : Les types qui possèdent des champs supprimables doivent être supprimables

Voir aussi