CA1816:正確呼叫 GC.SuppressFinalize
屬性 | 值 |
---|---|
規則識別碼 | CA1816 |
標題 | 正確呼叫 GC.SuppressFinalize |
類別 | 使用方式 |
修正程式是中斷或非中斷 | 不中斷 |
預設在 .NET 8 中啟用 | 建議 |
原因
此規則的違規原因可能是:
在未密封的類別中,實作 且不會呼叫 GC.SuppressFinalize 的方法 IDisposable.Dispose 。
不是 和 實作的方法 IDisposable.Dispose , 會呼叫 GC.SuppressFinalize 。
呼叫 GC.SuppressFinalize 和傳遞其他專案 的方法(C#) 或 Me (Visual Basic) 。
檔案描述
方法 IDisposable.Dispose 可讓使用者在物件可供垃圾收集使用之前隨時釋放資源。 IDisposable.Dispose如果呼叫 方法,它會釋放 物件的資源。 這不必要地進行最終處理。 IDisposable.Dispose 應該呼叫 GC.SuppressFinalize ,讓垃圾收集行程不會呼叫 物件的完成項。
若要防止具有完成項的衍生型別必須重新實 IDisposable 作並呼叫它,則沒有完成項的未密封型別仍應呼叫 GC.SuppressFinalize 。
如何修正違規
若要修正此規則的違規:
如果 方法是 的實作 Dispose ,請新增 對 GC.SuppressFinalize 的呼叫。
如果 方法不是 的 Dispose 實作,請移除 的 GC.SuppressFinalize 呼叫,或將它移至型別的實作 Dispose 。
將所有呼叫 GC.SuppressFinalize 變更為 以傳遞 此 (C#) 或 Me (Visual Basic) 。
如果型別不是要覆寫的,請將它標示為
sealed
。
隱藏警告的時機
只有在您刻意使用 GC.SuppressFinalize 來控制其他物件的存留期時,才隱藏此規則的警告。 如果 的 Dispose 實作未呼叫 GC.SuppressFinalize ,請勿隱藏此規則的警告。 在此情況下,無法抑制最終化會降低效能,而且沒有好處。
隱藏警告
如果您只想要隱藏單一違規,請將預處理器指示詞新增至原始程式檔以停用,然後重新啟用規則。
#pragma warning disable CA1816
// The code that's violating the rule is on this line.
#pragma warning restore CA1816
若要停用檔案、資料夾或專案的規則,請在組態檔 中將其嚴重性設定為 。 none
[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none
如需詳細資訊,請參閱 如何隱藏程式碼分析警告 。
違反 CA1816 的範例
此程式碼顯示呼叫 的方法 GC.SuppressFinalize ,但不會傳遞 這個 (C#) 或 Me (Visual Basic) 。 因此,此程式碼違反規則 CA1816。
Public Class DatabaseConnector
Implements IDisposable
Private _Connection As New SqlConnection
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
' Violates rules
GC.SuppressFinalize(True)
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If _Connection IsNot Nothing Then
_Connection.Dispose()
_Connection = Nothing
End If
End If
End Sub
End Class
public class DatabaseConnector : IDisposable
{
private SqlConnection? _Connection = new SqlConnection();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(true); // Violates rule
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_Connection != null)
{
_Connection.Dispose();
_Connection = null;
}
}
}
}
符合 CA1816 的範例
此範例示範傳遞這個 (C#) 或 Me (Visual Basic) 以正確呼叫 GC.SuppressFinalize 的方法。
Public Class DatabaseConnector
Implements IDisposable
Private _Connection As New SqlConnection
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If _Connection IsNot Nothing Then
_Connection.Dispose()
_Connection = Nothing
End If
End If
End Sub
End Class
public class DatabaseConnector : IDisposable
{
private SqlConnection? _Connection = new SqlConnection();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_Connection != null)
{
_Connection.Dispose();
_Connection = null;
}
}
}
}