CA2213: Disposable fields should be disposed
TypeName |
DisposableFieldsShouldBeDisposed |
CheckId |
CA2213 |
Category |
Microsoft.Usage |
Breaking Change |
Non Breaking |
Cause
A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type.
Rule Description
A type is responsible for disposing of all its unmanaged resources; this is accomplished by implementing IDisposable. This rule checks to see whether a disposable type T declares a field F that is an instance of a disposable type FT. For each field F, the rule attempts to locate a call to FT.Dispose. The rule searches the methods called by T.Dispose, and one level lower (the methods called by the methods called by FT.Dispose).
How to Fix Violations
To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field.
When to Suppress Warnings
It is safe to suppress a warning from this rule if you are not responsible for releasing the resource held by the field, or if the call to Dispose occurs at a deeper calling level than the rule checks.
Example
The following example shows a type TypeA that implements IDisposable (FT in the previosu discussion).
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);
}
}
}
The following example shows a type TypeB that violates this rule by declaring a field aFieldOfADisposableType (F in the previous discussion) as a disposable type (TypeA) and not calling Dispose on the field. TypeB corresponds to T in the previous discussion.
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);
}
}
}
See Also
Reference
Implementing Finalize and Dispose to Clean Up Unmanaged Resources