CA1816: GC.SuppressFinalize を正しく呼び出します
TypeName |
CallGCSuppressFinalizeCorrectly |
CheckId |
CA1816 |
[カテゴリ] |
Microsoft.使用方法 |
互換性に影響する変更点 |
なし |
原因
IDisposable.Dispose を実装するメソッドで、GC.SuppressFinalize を呼び出していません。
IDisposable.Dispose を実装しないメソッドで、GC.SuppressFinalize を呼び出しています。
メソッドが GC.SuppressFinalize を呼び出し、this (Visual Basic では Me) 以外の値を渡します。
規則の説明
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: 破棄できる型ではファイナライザーを宣言します