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