Condividi tramite


CA2213: I campi Disposable devono essere eliminati

Proprietà valore
ID regola CA2213
Title I campi eliminabili devono essere eliminati
Categoria Utilizzo
La correzione causa un'interruzione o meno Non causa un'interruzione
Abilitato per impostazione predefinita in .NET 9 No

Causa

Tipo che implementa System.IDisposable dichiara campi di tipi che implementano IDisposableanche . Il Dispose metodo del campo non viene chiamato dal Dispose metodo del tipo dichiarante.

Descrizione regola

Un tipo è responsabile dell'eliminazione di tutte le risorse non gestite. La regola CA2213 verifica se un tipo eliminabile ,ovvero uno che implementa IDisposable, T dichiara un campo F che è un'istanza di un tipo FTeliminabile . Per ogni campo F a cui è assegnato un oggetto creato localmente all'interno dei metodi o degli inizializzatori del tipo Tcontenitore , la regola tenta di individuare una chiamata a FT.Dispose. La regola cerca i metodi chiamati da T.Dispose e un livello inferiore , ovvero i metodi chiamati dai metodi chiamati da T.Dispose.

Nota

Oltre ai casi speciali, la regola CA2213 viene attivata solo per i campi assegnati a un oggetto eliminabile creato localmente all'interno dei metodi e degli inizializzatori del tipo contenitore. Se l'oggetto viene creato o assegnato all'esterno del tipo T, la regola non viene attivata. In questo modo si riduce il disturbo nei casi in cui il tipo contenitore non è responsabile dell'eliminazione dell'oggetto.

Casi speciali

La regola CA2213 può anche essere attivata per i campi dei tipi seguenti anche se l'oggetto assegnato non viene creato in locale:

Il passaggio di un oggetto di uno di questi tipi a un costruttore e quindi l'assegnazione a un campo indica un trasferimento di proprietà dispose al tipo appena costruito. Ovvero, il tipo appena costruito è ora responsabile dell'eliminazione dell'oggetto. Se l'oggetto non viene eliminato, si verifica una violazione di CA2213.

Come correggere le violazioni

Per correggere una violazione di questa regola, chiamare Dispose i campi di tipi che implementano IDisposable.

Quando eliminare gli avvisi

È possibile eliminare un avviso da questa regola se:

  • Il tipo contrassegnato non è responsabile del rilascio della risorsa contenuta nel campo , ovvero il tipo non dispone della proprietà dispose.
  • La chiamata a Dispose si verifica a un livello di chiamata più profondo rispetto ai controlli della regola
  • la proprietà dispose dei campi non è contenuta nel tipo contenitore.

Eliminare un avviso

Se si vuole eliminare una singola violazione, aggiungere direttive del preprocessore al file di origine per disabilitare e quindi riabilitare la regola.

#pragma warning disable CA2213
// The code that's violating the rule is on this line.
#pragma warning restore CA2213

Per disabilitare la regola per un file, una cartella o un progetto, impostarne la gravità none su nel file di configurazione.

[*.{cs,vb}]
dotnet_diagnostic.CA2213.severity = none

Per altre informazioni, vedere Come eliminare gli avvisi di analisi del codice.

Esempio

Il frammento di codice seguente mostra un tipo TypeA che implementa IDisposable.

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

Il frammento di codice seguente mostra un tipo TypeB che viola la regola CA2213 dichiarando un campo aFieldOfADisposableType come tipo eliminabile (TypeA) e non chiamando Dispose sul campo.

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

Per correggere la violazione, chiamare Dispose() sul campo eliminabile:

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

      disposed = true;

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

Vedi anche