CA2213: Disposable fields should be disposed
Note
This article applies to Visual Studio 2015. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here
Item | Value |
---|---|
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 previous 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);
}
}
}
Example
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);
}
}
}