Compartilhar via


Implementar IDisposable corretamente

TypeName

ImplementIDisposableCorrectly

CheckId

CA10634

Category (Categoria)

Microsoft.Design

Quebrando alterar

Não separável

Causa

IDisposable não foi implementado corretamente. Algumas das razões para esse problema são listados aqui:

  • IDisposable é re-implemented na classe.

  • Finalizar é re-overridden.

  • Dispose será substituída.

  • Não é público, Dispose() sealed ou chamada Dispose.

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

  • Em tipos sem lacre, Dispose() deve telefonar Dispose(true).

  • Para tipos sem lacre, a implementação de finalizar não telefonar Dispose(bool) uma ou ambas as ou o finalizador da classe maiúsculas.

Violação de qualquer um dos seguintes 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 telefonar Dipose(true) e finalize deve telefonar Dispose(false).Se você estiver criando um tipo de IDisposable raiz sem lacre, você deve definir Dispose(bool) e chamá-la.

Descrição da regra

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

Como corrigir violações

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

  • Remover IDisposable da lista de interfaces implementadas por {0} e substituir base de implementação Dispose de classe em vez disso.

  • Remover o finalizador do tipo {0}, substitua Dispose (bool descarte) e colocar a lógica de finalização no caminho de código em 'Descartar' for falso.

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

  • Certifique-se de que {0} é declarado sistema autônomo público e sealed ao mesmo tempo.

  • Renomear {0} 'Dispose' e certifique-se de que é declarado sistema autônomo público e sealed ao mesmo tempo.

  • Certifique-se de que {0} é declarado sistema autônomo protegido, virtual e deslacrada.

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

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

  • Se escrever uma classe de IDisposable raiz sem lacre, certifique-se de que a implementação de IDisposable segue o padrão descrito acima.

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 implementada em uma classe que usa gerenciada e nativo recursos:

public class Resource : IDisposable 
{
    private IntPtr nativeResource = Marhsal.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;
        }
    }
}