CA1816:正确调用 GC.SuppressFinalize
类型名 |
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 方法应调用基类的 Dispose