次の方法で共有


CA1816: GC.SuppressFinalize を正しく呼び出します

TypeName

CallGCSuppressFinalizeCorrectly

CheckId

CA1816

[カテゴリ]

Microsoft.使用方法

互換性に影響する変更点

なし

原因

規則の説明

IDisposable.Dispose メソッドを使用すると、オブジェクトがガベージ コレクションで使用できるようになる前であれば、任意のタイミングでリソースを解放できます。IDisposable.Dispose メソッドを呼び出すと、オブジェクトのリソースが解放されます。これにより、終了処理が不要になります。IDisposable.DisposeGC.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: 破棄できる型ではファイナライザーを宣言します

参照

関連項目

Implementing Finalize and Dispose