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: 破棄できる型ではファイナライザーを宣言します