CA2213:可處置的欄位應該受到處置
屬性 | 值 |
---|---|
規則識別碼 | CA2213 |
職稱 | 可處置的欄位應該受到處置 |
類別 | 使用方式 |
修正程式是中斷或非中斷 | 不中斷 |
預設在 .NET 9 中啟用 | No |
原因
實作 System.IDisposable 的型別會宣告同時實 IDisposable作 之型別的欄位。 宣告 Dispose 型別的 方法不會呼叫 Dispose 欄位的方法。
檔案描述
類型負責處置其所有 Unmanaged 資源。 規則 CA2213 會檢查可處置型別(也就是IDisposable實作的型別)T
是否宣告為可處置型FT
別實例的欄位F
。 針對在包含型T
別的方法或初始化表達式內指派本機建立之物件的每個欄位F
,規則會嘗試尋找 對FT.Dispose
的呼叫。 規則會搜尋 所 T.Dispose
呼叫的方法,並搜尋較低層級的方法(也就是 由呼叫的方法所呼叫 T.Dispose
的方法。
注意
除了 特殊案例之外,規則 CA2213 只會針對在包含類型的方法和初始化表達式內指派本機建立的可處置物件之字段引發。 如果物件是在 類型 T
之外建立或指派,則不會引發規則。 這可減少包含類型不負責處置物件的案例的雜訊。
特殊情況
即使未在本機建立指派的對象,規則 CA2213 也可以針對下列類型的欄位引發:
將其中一個型別的對象傳遞至建構函式,然後將它指派給字段,表示 處置擁有權傳送 至新建構的類型。 也就是說,新建構的類型現在負責處置 物件。 如果未處置物件,就會發生 CA2213 違規。
如何修正違規
若要修正此規則的違規,請在實作 的型IDisposable別字段上呼叫 Dispose 。
隱藏警告的時機
如果下列狀況,可以放心地隱藏此規則的警告:
- 標幟的類型不負責釋放欄位所持有的資源(也就是類型沒有 處置擁有權)
- 的 Dispose 呼叫發生在比規則檢查更深的呼叫層級
- 欄位的處置擁有權不是由包含的類型所持有。
隱藏警告
如果您只想要隱藏單一違規,請將預處理器指示詞新增至原始程式檔以停用,然後重新啟用規則。
#pragma warning disable CA2213
// The code that's violating the rule is on this line.
#pragma warning restore CA2213
若要停用檔案、資料夾或項目的規則,請在組態檔中將其嚴重性設定為 。none
[*.{cs,vb}]
dotnet_diagnostic.CA2213.severity = none
如需詳細資訊,請參閱 如何隱藏程式代碼分析警告。
範例
下列代碼段顯示實作IDisposable的型TypeA
別。
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);
}
}
下列代碼段顯示違反規則 CA2213 的類型 TypeB
,方法是將字段 aFieldOfADisposableType
宣告為可處置類型 (TypeA
), 而不是在欄位上呼叫 Dispose 。
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);
}
}
若要修正違規,請在可處置字段上呼叫 Dispose()
:
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
// Dispose of resources held by this instance.
aFieldOfADisposableType.Dispose();
disposed = true;
// Suppress finalization of this disposed instance.
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}