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