共用方式為


CA1816:正確呼叫 GC.SuppressFinalize

型別名稱

CallGCSuppressFinalizeCorrectly

CheckId

CA1816

分類

Microsoft。 使用方式

中斷變更

不中斷

原因

規則描述

在物件可讓記憶體回收之前,IDisposable.Dispose 方法讓使用者可以隨時釋放資源。 如果呼叫 IDisposable.Dispose 方法,則會釋放物件的資源。 這使得不需要最終處理。 IDisposable.Dispose 應該呼叫 GC.SuppressFinalize,以便讓記憶體回收行程不會呼叫物件的完成項。

 

若要避免使用完成項的衍生類別需要重新實作 [System.IDisposable] 以及呼叫它,未使用完成項的非密封型別仍應該呼叫 GC.SuppressFinalize

如何修正違規

若要修正此規則的違規情形:

如果方法是 Dispose 的實作,請將呼叫加入至 GC.SuppressFinalize

如果方法不是 Dispose 的實作,請移除對 GC.SuppressFinalize 的呼叫,或將其移至型別的 Dispose 實作。

變更 GC.SuppressFinalize 的所有呼叫以傳遞 this (Visual Basic 中的 Me)。

隱藏警告的時機

只有在考慮使用 GC.SuppressFinalize 控制其他物件的存留期時,才隱藏這項規則的警告。 如果 Dispose 的實作並未呼叫 GC.SuppressFinalize,請勿隱藏這項規則的警告。 在這種情況下,無法隱藏最終化將會降低效能且不提供任何好處。

範例

下列範例會示範不正確呼叫 GC.SuppressFinalize 的方法。

Imports System
Imports System.Data.SqlClient

Namespace Samples

    Public Class DatabaseConnector
        Implements IDisposable

        Private _Connection As New SqlConnection

        Public Sub Dispose() Implements IDisposable.Dispose
            Dispose(True)
            GC.SuppressFinalize(True)   ' Violates rules
        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

End Namespace
using System;
using System.Data.SqlClient;
namespace Samples
{
    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;
                }
            }
        }
    }
}

下列範例示範以正確方式呼叫 GC.SuppressFinalize 的方法。

Imports System
Imports System.Data.SqlClient

Namespace Samples

    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

End Namespace
using System;
using System.Data.SqlClient;

namespace Samples
{
    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;
                }
            }
        }
    }
}

相關規則

CA2215:Dispose 方法應該呼叫基底類別處置

CA2216:可處置型別應該宣告完成項

請參閱

參考

實作 Finalize 和 Dispose 以清除 Unmanaged 資源