CA2213:应释放可释放的字段
类型名 |
DisposableFieldsShouldBeDisposed |
CheckId |
CA2213 |
类别 |
Microsoft.Usage |
是否重大更改 |
否 |
原因
实现 System.IDisposable 的类型声明同样实现 IDisposable 的类型的字段。 字段的 Dispose 方法不是由声明类型的 Dispose 方法调用。
规则说明
类型负责释放其全部非托管资源,这是通过实现 IDisposable 完成的。 该规则进行检查,以确定可释放类型 T 是否声明字段 F,该字段为可释放类型 FT 的实例。 对于每个字段 F,该规则尝试定位对 FT.Dispose 的调用。 该规则搜索 T.Dispose 调用的方法及下一级方法(由 FT.Dispose 调用的方法所调用的方法)。
如何解决冲突
要修复与该规则的冲突,如果您负责分配和释放字段中包含的非托管资源,请在实现 IDisposable 的类型的字段上调用 Dispose。
何时禁止显示警告
如果您不负责释放字段包含的资源,或者对 Dispose 的调用发生在该规则所检查的调用级别以下的级别中,则可以安全地禁止显示此规则发出的警告。
示例
下面的示例演示实现 IDisposable(上文中讨论的 FT)的类型 TypeA。
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);
}
}
}