Compartilhar via


CA1063: Implementar IDisposable corretamente

TypeName

ImplementIDisposableCorrectly

CheckId

CA1063

<strong>Categoria</strong>

Microsoft.design

Alteração significativa

Não-separável

Causa

IDisposablenão é implementada corretamente. Algumas das razões para esse problema estão listados aqui:

  • IDisposable é re-implemented na classe.

  • Finalizar é re-overridden.

  • Dispose é substituído.

  • Dispose () não é público, selado ou chamada de Dispose.

  • Dispose (bool) não está protegido, virtual ou sem lacre.

  • Tipos sem lacre, Dispose () deve chamar Dispose(true).

  • Para tipos sem lacre, a implementação de Finalize não chamar Dispose (bool) uma ou ambas as ou o finalizador da classe caso.

Violação de qualquer um desses padrões irá disparar esse aviso.

Cada raiz sem lacre IDisposable tipo deve fornecer seu próprio método de Dispose (bool) de void de virtual protegido. Dispose () deve chamar Dipose(true) e Finalize deve chamar Dispose(false). Se você estiver criando um tipo de IDisposable raiz sem lacre, você deve definir Dispose (bool) e chamá-lo. Para obter mais informações, consulte Limpeza de recursos não gerenciados na Diretrizes de Design para desenvolvimento bibliotecas de classe seção o.Documentação do NET Framework.

Descrição da regra

Todos os tipos de IDisposable devem implementar corretamente o padrão Dispose.

Como corrigir violações

Examine o seu código e determinar qual das seguintes resoluções corrigirá essa violação.

  • Remova IDisposable da lista de interfaces que são implementados por {0} e substituem a implementação de Dispose de classe base em vez disso.

  • Remova o finalizador do tipo {0}, substituir Dispose (bool descartando) e colocar a lógica de finalização no caminho do código onde 'Descartar' é false.

  • Remover {0}, substituir Dispose (bool descartando) e colocar a lógica de dispose no caminho do código onde 'Descartar' é verdade.

  • Certifique-se de que {0} é declarado como público e sealed.

  • Renomear {0} 'Dispose' e certifique-se de que é declarado como público e sealed.

  • Certifique-se de que {0} é declarado como protegido, virtual e sem lacre.

  • Modificar {0} para que ele chama o Dispose(true), em seguida, chama GC.SuppressFinalize na instância do objeto atual ('this' ou 'Me' em Visual Basic) e em seguida, retorna.

  • Modificar {0} para que ele chama o Dispose(false) e, em seguida, retorna.

  • Se você estiver escrevendo uma classe de IDisposable raiz sem lacre, certifique-se de que a implementação de IDisposable segue o padrão que é descrito anteriormente nesta seção.

Quando suprimir avisos

Não suprimir um aviso da regra.

Exemplo de pseudocódigo

O pseudocódigo a seguir fornece um exemplo geral de como Dispose (bool) deve ser implementado em uma classe que usa gerenciada e recursos nativos.

public class Resource : IDisposable 
{
    private IntPtr nativeResource = Marshal.AllocHGlobal(100);
    private AnotherResource managedResource = new AnotherResource();

// Dispose() calls Dispose(true)
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    // NOTE: Leave out the finalizer altogether if this class doesn't 
    // own unmanaged resources itself, but leave the other methods
    // exactly as they are. 
    ~Resource() 
    {
        // Finalizer calls Dispose(false)
        Dispose(false);
    }
    // The bulk of the clean-up code is implemented in Dispose(bool)
    protected virtual void Dispose(bool disposing)
    {
        if (disposing) 
        {
            // free managed resources
            if (managedResource != null)
            {
                managedResource.Dispose();
                managedResource = null;
            }
        }
        // free native resources if there are any.
        if (nativeResource != IntPtr.Zero) 
        {
            Marshal.FreeHGlobal(nativeResource);
            nativeResource = IntPtr.Zero;
        }
    }
}