Condividi tramite


I campi eliminabili devono essere eliminati

Aggiornamento: novembre 2007

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).

Correzione di 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 pulitura delle risorse non gestite

System.IDisposable