CA2213:可處置的欄位應該受到處置
型別名稱 |
DisposableFieldsShouldBeDisposed |
CheckId |
CA2213 |
分類 |
Microsoft.Usage |
中斷變更 |
不中斷 |
原因
實作 System.IDisposable 的型別宣告了也實作 IDisposable 之型別的欄位。宣告型別的 Dispose 方法不會呼叫欄位的 Dispose 方法。
規則描述
型別會負責處置它的所有 Unmanaged 資源,透過實作 IDisposable 便可達成此目的。此規則會檢查可處置型別 T 所宣告的欄位 F 是否為可處置型別 FT 的執行個體。對每個欄位 F 而言,此規則會嘗試找出對 FT.Dispose 的呼叫。此規則會搜尋 T.Dispose 所呼叫的方法和更下一層的方法 (由 FT.Dispose 呼叫的方法所呼叫的方法)。
如何修正違規
若要修正此規則的違規情形,而且您也負責配置和釋放欄位所保留的 Unmanaged 資源,請在屬於實作 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);
}
}
}