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.

Configurare l'analisi del flusso di dati

Usare le opzioni seguenti per configurare l'analisi del flusso di dati per questa regola:

È possibile configurare queste opzioni solo per questa regola, per tutte le regole a cui si applicano o per tutte le regole di questa categoria (Sicurezza) a cui si applicano. Per altre informazioni, vedere opzioni di configurazione delle regole di qualità 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