Pergunta

No Visual Studio, quando digito a linha "Implements IDisposable", o IDE adiciona automaticamente:

  • a disposedValue variável de membro
  • a Sub Dispose() Implements IDisposable.Dispose
  • a Sub Dispose(ByVal disposing As Boolean)

O Dispose() deve ser deixado sozinho, e o código de limpeza deve ser colocado Dispose(disposing).

No entanto, o Descartar padrão de finalização diz que você também deve substituir Sub Finalize() chamar Dispose(False).Por que o IDE também não adiciona isso?Devo adicioná-lo sozinho ou é de alguma forma chamado implicitamente?

EDITAR: Alguma ideia de por que o IDE adiciona automaticamente 80% do material necessário, mas deixa de fora o método Finalize?O objetivo desse tipo de recurso não é ajudar você não esquecer essas coisas?

EDITAR2: Obrigado a todos pelas excelentes respostas, agora faz todo o sentido!

Foi útil?

Solução

Se você realmente estiver segurando recursos não gerenciados que não serão limpos automaticamente pelo coletor de lixo e limpando-os em seu dispede (), então sim, você deve fazer o mesmo em Finalize ().

Se você está implementando o IDisposable por algum outro motivo, a implementação do finalize () não é necessária.

A pergunta básica é a seguinte: se o dispede () não fosse chamado e seu lixo de objeto coletado, o memória vazaria? Se sim, implemente finalize. Se não, você não precisa. Além disso, evite a implementação da finalize "apenas porque é mais seguro". Objetos com finalizadores personalizados podem precisar de dois passes GC para libertá -los - uma vez para colocá -los na fila de finalizadores pendentes e um segundo passe para realmente libertar sua memória.

Outras dicas

Não, você não precisa ter o Finalize, a menos que tenha recursos não gerenciados para limpar.

Na maioria dos casos, o motivo pelo qual uma classe é descartável é porque ela mantém referências a outros objetos IDisposable gerenciados.Neste caso, nenhum método Finalize é necessário ou desejável.

Implements IDisposable

Public Overloads Sub Dispose() Implements IDisposable.Dispose

    Dispose(True)
    GC.SuppressFinalize(Me)

End Sub

Protected Overloads Sub Dispose(ByVal disposing As Boolean)

    If disposing Then
        ' Free other state (managed objects).
    End If
    ' Free your own state (unmanaged objects).
    ' Set large fields to null.
End Sub

Protected Overrides Sub Finalize()

    Dispose(False)
    MyBase.Finalize()

End Sub

Como outros disseram, você não precisa implementar um finalizador, a menos que esteja mantendo recursos não gerenciados diretamente. Além disso, supondo que você esteja trabalhando no .NET 2.0 ou posterior, é improvável que você precise implementar um finalizador, porque normalmente o SafeHandle pode ser usado para envolver seus recursos não gerenciados.

Eu escrevi a Postagem de blog bastante longa Cobrindo o plano de fundo e a implementação de idispos e finalizadores há algum tempo, o que pode valer a pena ler se você não estiver totalmente claro sobre isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top