CA1816: chamar GC.SuppressFinalize corretamente
TypeName |
CallGCSuppressFinalizeCorrectly |
CheckId |
CA1816 |
Categoria |
Microsoft.Uso |
Alteração Significativa |
Sem Quebra |
Causa
Um método que é uma implementação de IDisposable.Dispose não chama GC.SuppressFinalize.
Um método que não é uma implementação de IDisposable.Dispose chama GC.SuppressFinalize.
Chama um método GC.SuppressFinalize e passa algo diferente do (i no Visual Basic).
Descrição da Regra
O método de IDisposable.Dispose permite que os usuários liberar a qualquer momento recursos antes do objeto que fica disponível para coleta de lixo.Se o método de IDisposable.Dispose é chamado, libera recursos do objeto.Isso torna o acabamento desnecessário.IDisposable.Dispose deve chamar GC.SuppressFinalize assim que o coletor de lixo não chama o finalizador do objeto.
Para evitar tipos derivados com os finalizers do têm que implementam novamente [System.IDisposable] e chamar, tipos unsealed sem finalizers ainda deve chamar GC.SuppressFinalize.
Como Corrigir Violações
Para corrigir uma violação dessa regra:
Se o método for uma implementação de Dispose, adicione uma chamada a GC.SuppressFinalize.
Se o método não é uma implementação de Dispose, ou remover a chamada a GC.SuppressFinalize ou movê-lo para a implementação de Dispose do tipo.
Alterar qualquer chamada paraGC.SuppressFinalize para transmitir isso a (no Visual Basic).
Quando Suprimir Alertas
Suprima apenas um aviso dessa regra se você estiver usando deliberando GC.SuppressFinalize para controlar o tempo de vida de outros objetos.Não suprima um aviso dessa regra se uma implementação de Dispose não chama GC.SuppressFinalize.Nessa situação, não suprime o acabamento prejudica o desempenho e não fornece nenhum benefício.
Exemplo
O exemplo a seguir mostra um método que chama GC.SuppressFinalizeincorretamente.
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;
}
}
}
}
}
O exemplo a seguir mostra um método que chama GC.SuppressFinalizecorretamente.
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;
}
}
}
}
}
Regras Relacionadas
CA2215: os métodos de descarte devem chamar o descarte da classe base
CA2216: os tipos descartáveis devem declarar o finalizador