Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
| Property | Valor |
|---|---|
| ID da regra | CA1816 |
| Título | Chamar GC.SuppressFinalize corretamente |
| Categoria | Usage |
| Correção interruptiva ou sem interrupção | Sem interrupção |
| Habilitado por padrão no .NET 10 | Como sugestão |
Causa
As violações dessa regra podem ser causadas por:
Em uma classe não selada, 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 chamadas 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 método IDisposable.Dispose for chamado, ele liberará 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 precisem reimplementar IDisposable e chamá-los, tipos não selados 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 de Dispose, remova a chamada para GC.SuppressFinalize ou mova-a para a implementação do tipo Dispose.
Altere todas as chamadas para GC.SuppressFinalize para passar isso (C#) ou Me (Visual Basic).
Se o tipo não for feito para ser substituído, marque-o como
sealed.
Quando suprimir avisos
Suprime apenas um aviso dessa regra se você estiver usando GC.SuppressFinalize deliberadamente para controlar o tempo de vida de outros objetos. Não suprime um aviso dessa 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 oferece benefícios.
Suprimir um aviso
Para suprimir apenas uma violação, adicione diretivas de pré-processador ao arquivo de origem a fim de desabilitar e, em seguida, reabilitar 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 em um arquivo, uma pasta ou um projeto, defina a severidade como none no arquivo de configuração.
[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none
Para obter mais informações, confira Como suprimir avisos de análise de código.
Exemplo que viola CA1816
Esse 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 MyStreamClass
Implements IDisposable
Private _stream As New MemoryStream
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
' Violates rule.
GC.SuppressFinalize(True)
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If _stream IsNot Nothing Then
_stream.Dispose()
_stream = Nothing
End If
End If
End Sub
End Class
public class MyStreamClass : IDisposable
{
private MemoryStream? _stream = new();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(true); // Violates rule
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_stream?.Dispose();
_stream = null;
}
}
}
Exemplo que satisfaz CA1816
Este exemplo mostra um método que chama GC.SuppressFinalize corretamente passando isso (C#) ou Me (Visual Basic).
Public Class MyStreamClass
Implements IDisposable
Private _stream As New MemoryStream
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 _stream IsNot Nothing Then
_stream.Dispose()
_stream = Nothing
End If
End If
End Sub
End Class
public class MyStreamClass : IDisposable
{
private MemoryStream? _stream = new();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_stream?.Dispose();
_stream = null;
}
}
}
Regras relacionadas
- CA2215: Métodos Dispose devem chamar o descarte da classe base
- CA2216: Tipos descartáveis devem declarar o finalizador