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 FT
eliminabile . Per ogni campo F
a cui è assegnato un oggetto creato localmente all'interno dei metodi o degli inizializzatori del tipo T
contenitore , 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:
- interprocedural_analysis_kind
- max_interprocedural_lambda_or_local_function_call_chain
- max_interprocedural_method_call_chain
- points_to_analysis_kind
- copy_analysis
- sufficient_IterationCount_for_weak_KDF_algorithm
È 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);
}
}
}