CA1816: Ligue para GC. SuppressFinalize corretamente
Property | valor |
---|---|
ID da regra | CA1816 |
Título | Ligue para o GC. SuppressFinalize corretamente |
Categoria | Utilização |
A correção está quebrando ou não quebrando | Sem quebra |
Habilitado por padrão no .NET 8 | Como sugestão |
Motivo
As violações desta regra podem ser causadas por:
Em uma classe sem lacre, um método que é uma implementação de IDisposable.Dispose e não chama GC.SuppressFinalize.
Um método que não é uma implementação de IDisposable.Dispose e chama GC.SuppressFinalize.
Um método que chama GC.SuppressFinalize e passa algo diferente disso (C#) ou Me (Visual Basic).
Descrição da regra
O IDisposable.Dispose método permite que os usuários liberem recursos a qualquer momento antes que o objeto fique disponível para coleta de lixo. Se o IDisposable.Dispose método é chamado, ele libera recursos do objeto. Isso torna a finalização desnecessária. IDisposable.Dispose deve chamar GC.SuppressFinalize para que o coletor de lixo não chame o finalizador do objeto.
Para evitar que tipos derivados com finalizadores tenham que reimplementar IDisposable e chamá-lo, os tipos sem lacre sem finalizadores ainda devem chamar GC.SuppressFinalize.
Como corrigir violações
Para corrigir uma violação desta regra:
Se o método for uma implementação de Dispose, adicione uma chamada a GC.SuppressFinalize.
Se o método não for uma implementação do , remova a chamada ou GC.SuppressFinalize mova-a para a implementação do DisposeDispose tipo.
Altere todas as chamadas para GC.SuppressFinalize passar isso (C#) ou Me (Visual Basic).
Se o tipo não se destinar a ser substituído, marque-o como
sealed
.
Quando suprimir avisos
Apenas suprima um aviso desta regra se estiver deliberadamente a utilizar GC.SuppressFinalize para controlar o tempo de vida de outros objetos. Não suprima um aviso desta regra se uma implementação de Dispose não chamar GC.SuppressFinalize. Nessa situação, não suprimir a finalização degrada o desempenho e não fornece benefícios.
Suprimir um aviso
Se você quiser apenas suprimir uma única violação, adicione diretivas de pré-processador ao seu arquivo de origem para desativar e, em seguida, reativar a regra.
#pragma warning disable CA1816
// The code that's violating the rule is on this line.
#pragma warning restore CA1816
Para desabilitar a regra para um arquivo, pasta ou projeto, defina sua severidade como none
no arquivo de configuração.
[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none
Para obter mais informações, consulte Como suprimir avisos de análise de código.
Exemplo que viola CA1816
Este código mostra um método que chama GC.SuppressFinalize, mas não passa isso (C#) ou Me (Visual Basic). Como resultado, esse código viola a regra CA1816.
Public Class DatabaseConnector
Implements IDisposable
Private _Connection As New SqlConnection
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
' Violates rules
GC.SuppressFinalize(True)
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
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;
}
}
}
}
Exemplo que satisfaz CA1816
Este exemplo mostra um método que chama corretamente passando isso (C#) ou Me (Visual Basic).GC.SuppressFinalize
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
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 conexas
- CA2215: Os métodos de descarte devem chamar a classe base dispose
- CA2216: Tipos descartáveis devem declarar finalizador