事件
CA1816:正確呼叫 GC.SuppressFinalize
屬性 | 值 |
---|---|
規則識別碼 | CA1816 |
職稱 | 正確呼叫 GC.SuppressFinalize |
類別 | 使用方式 |
修正程式是中斷或非中斷 | 不中斷 |
預設在 .NET 9 中啟用 | 建議 |
此規則的違規原因可能是:
在未密封的類別中,實作 且不會呼叫 IDisposable.Dispose的方法GC.SuppressFinalize。
不是 與實作的方法 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
[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none
如需詳細資訊,請參閱 如何隱藏程式代碼分析警告。
此程式代碼顯示呼叫 的方法 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;
}
}
}
}
此範例示範傳遞這個 (C#) 或 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;
}
}
}
}