Compartilhar via


CA1816: Chamar GC.SuppressFinalize corretamente

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:

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:

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;
        }
    }
}

Confira também