VB.NET – Следует ли добавлять метод Finalize при реализации IDisposable?

StackOverflow https://stackoverflow.com/questions/113267

Вопрос

В Visual Studio, когда я печатаю строку "Implements IDisposable", IDE автоматически добавляет:

  • а disposedValue переменная-член
  • а Sub Dispose() Implements IDisposable.Dispose
  • а Sub Dispose(ByVal disposing As Boolean)

А Dispose() следует оставить в покое и вставить код очистки Dispose(disposing).

Однако Удалить шаблон завершения говорит, что вам также следует переопределить Sub Finalize() звонить Dispose(False).Почему IDE также не добавляет это?Должен ли я добавить его сам или он как-то вызывается неявно?

РЕДАКТИРОВАТЬ: Есть идеи, почему IDE автоматически добавляет 80% необходимого материала, но не учитывает метод Finalize?Разве весь смысл этой функции не в том, чтобы помочь вам нет забыть эти вещи?

РЕДАКТИРОВАТЬ2: Спасибо всем за отличные ответы, теперь это имеет смысл!

Это было полезно?

Решение

Если вы действительно храните неуправляемые ресурсы, которые не будут автоматически очищаться сборщиком мусора и очищать их в Dispose(), то да, вам следует сделать то же самое в Finalize().

Если вы реализуете IDisposable по какой-либо другой причине, реализация Finalize() не требуется.

Основной вопрос заключается в следующем:Если бы Dispose() не вызывался и ваш объектный мусор собирался, произошла бы утечка памяти?Если да, реализуйте Finalize.Если нет, то вам это не нужно.Кроме того, избегайте реализации Finalize «только потому, что это безопаснее».Объектам с пользовательскими финализаторами потенциально могут потребоваться два прохода GC, чтобы освободить их: один раз, чтобы поместить их в очередь ожидающих финализаторов, и второй проход, чтобы фактически освободить их память.

Другие советы

Нет, Finalize вам не нужен, если у вас нет неуправляемых ресурсов, которые нужно очистить.

В большинстве случаев класс является одноразовым потому, что он хранит ссылки на другие управляемые объекты IDisposable.В этом случае метод Finalize не является необходимым или желательным.

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

Как говорили другие, вам не нужно реализовывать финализатор, если вы напрямую не владеете неуправляемыми ресурсами.Кроме того, если вы работаете в .NET 2.0 или более поздней версии, маловероятно, что вам когда-либо понадобится реализовать финализатор, поскольку обычно SafeHandle можно использовать для упаковки неуправляемых ресурсов.

Я написал довольно длинный пост в блоге некоторое время назад мы рассказывали об истории и реализации IDisposable и финализаторов, которые, возможно, стоит прочитать, если вы не совсем разбираетесь в этом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top