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