VB.NET - 实现 IDisposable 时是否应该添加 Finalize 方法?

发布于 2024-07-06 00:22:58 字数 800 浏览 13 评论 0原文

在 Visual Studio 中,当我键入“Implements IDisposable”行时,IDE 会自动添加:

  • disposeValue 成员变量
  • Sub Dispose() Implements IDisposable.Dispose< /code>
  • a Sub Dispose(ByVal disusing As Boolean)

应该保留 Dispose(),清理代码应该放在 Dispose(disusing )

但是 Dispose Finalize Pattern 表示您应该还重写 Sub Finalize() 以调用 Dispose(False)。 为什么IDE不添加这个呢? 我必须自己添加它,还是以某种方式隐式调用它?

编辑:知道为什么 IDE 会自动添加 80% 的必需内容但忽略 Finalize 方法吗? 这种功能的全部意义不就是帮助您忘记这些事情吗?

编辑2:谢谢大家的出色回答,现在这使得完美的感觉!

In Visual Studio, when I type the line "Implements IDisposable", the IDE automatically adds:

  • a disposedValue member variable
  • a Sub Dispose() Implements IDisposable.Dispose
  • a Sub Dispose(ByVal disposing As Boolean)

The Dispose() should be left alone, and the clean up code should be put in Dispose(disposing).

However the Dispose Finalize Pattern says you should also override Sub Finalize() to call Dispose(False). Why doesn't the IDE also add this? Must I add it myself, or is it somehow called implicitly?

EDIT: Any idea why the IDE automatically adds 80% of the required stuff but leaves out the Finalize method? Isn't the whole point of this kind of feature to help you not forget these things?

EDIT2: Thank you all for your excellent answers, this now makes perfect sense!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

花想c 2024-07-13 00:22:58

如果您实际上持有垃圾收集器不会自动清理的非托管资源并在 Dispose() 中清理它们,那么是的,您应该在 Finalize() 中执行相同的操作。

如果您出于其他原因实现 IDisposable,则不需要实现 Finalize()。

基本问题是:如果没有调用 Dispose() 并且您的对象被垃圾收集,内存会泄漏吗? 如果是,则执行Finalize。 如果没有,则不需要。 另外,避免“仅仅因为它更安全”而实现 Finalize。 具有自定义终结器的对象可能需要两次 GC 传递来释放它们——一次将它们放入挂起的终结器队列,第二次传递实际释放其内存。

If you actually are holding non-managed resources that will not be automatically cleaned up by the garbage collector and cleaning those up in your Dispose(), then yes, you should do the same in Finalize().

If you're implementing IDisposable for some other reason, implementing Finalize() isn't required.

The basic question is this: If Dispose() wasn't called and your object garbage collected, would memory leak? If yes, implement Finalize. If no, you don't need to. Also, avoid implementing Finalize "just because it's safer". Objects with custom finalizers can potentially need two GC passes to free them -- once to put them on the pending finalizers queue, and a second pass to actually free their memory.

原来是傀儡 2024-07-13 00:22:58
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
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
尝蛊 2024-07-13 00:22:58

不,除非您有非托管资源需要清理,否则您不需要 Finalize。

在大多数情况下,类是一次性的的原因是它保留对其他托管 IDisposable 对象的引用。 在这种情况下,不需要或不需要 Finalize 方法。

No, you don't need to have Finalize unless you have unmanaged resources to clean up.

In most cases the reason a class is disposable is because it keeps references to other managed IDisposable objects. In this case no Finalize method is necessary or desirable.

遗弃M 2024-07-13 00:22:58

正如其他人所说,除非您直接持有非托管资源,否则您不需要实现终结器。 另外,假设您使用 .NET 2.0 或更高版本,您不太可能需要实现终结器,因为通常 SafeHandle 可用于包装非托管资源。

我写了一个相当很长的博客文章介绍了 IDisposable 和终结器的背景和实现,如果您不完全清楚它可能值得一读。

As others have said, you don't need to implement a finalizer unless you're directly holding unmanaged resources. Also, assuming you're working in .NET 2.0 or later, it's unlikely you'll ever need to implement a finalizer because typically SafeHandle can be used to wrap your unmanaged resources.

I wrote a fairly long blog post covering the background and implementation of IDisposable and finalizers a while back, which may be worth a read if you're not totally clear about it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文