Condividi tramite


CA2213: I campi Disposable devono essere eliminati

TypeName

DisposableFieldsShouldBeDisposed

CheckId

CA2213

Category

Microsoft.Usage

Breaking Change

Non sostanziale

Causa

Un tipo che implementa System.IDisposable dichiara i campi di tipi che implementano anch'essi IDisposable. Il metodo Dispose del campo non viene chiamato dal metodo Dispose del tipo dichiarante.

Descrizione della regola

Un tipo è responsabile dell'eliminazione di tutte le risorse non gestite. Questa operazione viene eseguita mediante l'implementazione di IDisposable. Questa regola controlla se un tipo Disposable T dichiara un campo F costituito da un'istanza di un tipo Disposable FT. Per ogni campo F, la regola tenta di individuare una chiamata a FT.Dispose. La regola cerca i metodi chiamati da T.Dispose e il livello inferiore (metodi chiamati da metodi chiamati da FT.Dispose).

Come correggere le violazioni

Per correggere una violazione di questa regola, chiamare Dispose su campi di tipi che implementano IDisposable se si è responsabili dell'allocazione e del rilascio delle risorse non gestite contenute in un campo.

Esclusione di avvisi

L'esclusione di un avviso da questa regola è sicura se non si è responsabili del rilascio della risorsa contenuta dal campo o se la chiamata a Dispose viene effettuata a un livello di chiamata più profondo rispetto a quanto controllato dalla regola.

Esempio

Nell'esempio riportato di seguito viene illustrato un tipo TypeA che implementa IDisposable (FT nella spiegazione precedente).

using System;  

namespace UsageLibrary
{
    public class  TypeA :IDisposable
    {

        protected virtual void Dispose(bool disposing) 
        {
            if (disposing) 
            {
                // Dispose managed resources
            }

            // Free native resources
        }

        public void Dispose()
        {

                Dispose(true);

                GC.SuppressFinalize(this);

        }

        // Disposable types implement a finalizer.
        ~TypeA()
        {
            Dispose(false);
        }
    }
}

Nell'esempio riportato di seguito viene illustrato un tipo TypeB che viola la regola dichiarando un campo aFieldOfADisposableType (F nella spiegazione precedente) come tipo Disposable (TypeA) e non chiamando Dispose sul campo. TypeB corrisponde a T nella spiegazione precedente.

using System;  

namespace UsageLibrary
{
   public class  TypeB : IDisposable
   {
      // Assume this type has some unmanaged resources.
      TypeA aFieldOfADisposableType = new TypeA();
      private bool disposed = false;

      protected virtual void Dispose(bool disposing) 
      {
         if (!disposed) 
         {
            // Dispose of resources held by this instance.

            // Violates rule: DisposableFieldsShouldBeDisposed.
            // Should call aFieldOfADisposableType.Dispose();

            disposed = true;
             // Suppress finalization of this disposed instance.
             if (disposing)
             {
                 GC.SuppressFinalize(this);
             }
         }
      }

      public void Dispose()
      {
         if (!disposed)
         {
            // Dispose of resources held by this instance.
            Dispose(true);
         }
      }

      // Disposable types implement a finalizer.
      ~TypeB()
      {
         Dispose(false);
      }
   }
}

Vedere anche

Riferimenti

Implementazione dei metodi Finalize e Dispose per la pulizia delle risorse non gestite

System.IDisposable