Partilhar via


CA1816: Call GC.SuppressFinalize correctly

Note

This article applies to Visual Studio 2015. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here

Item Value
TypeName CallGCSuppressFinalizeCorrectly
CheckId CA1816
Category Microsoft. Usage
Breaking Change Non Breaking

Cause

Rule Description

The System.IDisposable.Dispose method lets users release resources at any time before the object becoming available for garbage collection. If the System.IDisposable.Dispose method is called, it frees resources of the object. This makes finalization unnecessary. System.IDisposable.Dispose should call System.GC.SuppressFinalize so the garbage collector does not call the finalizer of the object.

To prevent derived types with finalizers from having to re-implement [System.IDisposable]() and to call it, unsealed types without finalizers should still call System.GC.SuppressFinalize.

How to Fix Violations

To fix a violation of this rule:

If the method is an implementation of Dispose, add a call to System.GC.SuppressFinalize.

If the method is not an implementation of Dispose, either remove the call to System.GC.SuppressFinalize or move it to the type's Dispose implementation.

Change all calls to System.GC.SuppressFinalize to pass this (Me in Visual Basic).

When to Suppress Warnings

Only suppress a warning from this rule if you are deliberating using System.GC.SuppressFinalize to control the lifetime of other objects. Do not suppress a warning from this rule if an implementation of Dispose does not call System.GC.SuppressFinalize. In this situation, failing to suppress finalization degrades performance and provide no benefits.

Example

The following example shows a method that incorrectly calls System.GC.SuppressFinalize.

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;
                }
            }
        }
    }
}
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

Example

The following example shows a method that correctly calls System.GC.SuppressFinalize.

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;
                }
            }
        }
    }
}
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

CA2215: Dispose methods should call base class dispose

CA2216: Disposable types should declare finalizer

See Also

Dispose Pattern