分享方式:


CA1816:正確呼叫 GC.SuppressFinalize

屬性
規則識別碼 CA1816
標題 正確呼叫 GC.SuppressFinalize
類別 使用方式
修正程式是中斷或非中斷 不中斷
預設在 .NET 8 中啟用 建議

原因

此規則的違規原因可能是:

檔案描述

方法 IDisposable.Dispose 可讓使用者在物件可供垃圾收集使用之前隨時釋放資源。 IDisposable.Dispose如果呼叫 方法,它會釋放 物件的資源。 這不必要地進行最終處理。 IDisposable.Dispose 應該呼叫 GC.SuppressFinalize ,讓垃圾收集行程不會呼叫 物件的完成項。

若要防止具有完成項的衍生型別必須重新實 IDisposable 作並呼叫它,則沒有完成項的未密封型別仍應呼叫 GC.SuppressFinalize

如何修正違規

若要修正此規則的違規:

隱藏警告的時機

只有在您刻意使用 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;
            }
        }
    }
}

另請參閱