CA2213: 破棄可能なフィールドは破棄されなければなりません
TypeName |
DisposableFieldsShouldBeDisposed |
CheckId |
CA2213 |
[カテゴリ] |
Microsoft.Usage |
互換性に影響する変更点 |
なし |
原因
System.IDisposable を実装する型が、IDisposable を実装している型も持つフィールドを宣言しています。このフィールドの Dispose メソッドは、宣言している型の Dispose メソッドから呼び出されていません。
規則の説明
型は、アンマネージ リソースのすべての破棄に責任があります。これは、IDisposable を実装することで実現します。この規則で、破棄できる型 T が、破棄できる型 FT のインスタンスであるフィールド F を宣言しているかどうかがチェックされます。F フィールドごとに、FT.Dispose の呼び出し位置が特定されます。また、T.Dispose から呼び出されたメソッドと、1 レベル低いメソッド (FT.Dispose によって呼び出されたメソッドから呼び出されたメソッド) を検索します。
違反の修正方法
IDisposable を実装する型を持つフィールドで保持されるアンマネージ リソースの割り当てと解放を行うコードを担当している場合、この規則違反を修正するには、このフィールドで Dispose を呼び出します。
警告を抑制する状況
このフィールドで保持されているリソースを解放するコードを担当していない場合、または Dispose の呼び出しがこの規則でチェックされる呼び出しレベルよりも深いレベルで発生する場合は、この規則による警告を抑制しても安全です。
使用例
IDisposable を実装する型 TypeA (上記の説明では FT) を次の例に示します。
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);
}
}
}
この規則に違反する型 TypeB を次の例に示します。この型は、フィールド aFieldOfADisposableType (上の説明では F) を破棄できる型 (TypeA) として宣言し、フィールドで Dispose を呼び出していないため、規則違反です。TypeB は、上の説明の T に相当します。
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);
}
}
}