决赛选手有什么用?
我已经用 .NET 编程四年了(主要是 C#),并且广泛使用 IDiposable,但我尚未发现需要终结器。 决赛选手有什么用?
I have been programming in .NET for four years (mostly C#) and I use IDiposable extensively, but I am yet to find a need for a finaliser. What are finalisers for?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
终结器是确保正确清理某些内容的最后一搏,通常为包装非托管资源的对象保留,例如不会被垃圾收集的非托管句柄等。
编写终结器确实很少见。 幸运的是(与
IDisposable
不同),终结器不需要传播; 因此,如果您有一个带有终结器的ClassA
和一个包装ClassA
的ClassB
,则ClassB
不需要终结器 - 但很可能ClassA
和ClassB
都会实现IDisposable
。对于托管代码,
IDisposable
通常就足够了。 即使您没有正确清理,最终托管对象也会被收集(假设它们已被释放)。A finalizer is a last ditch attempt to ensure that something is cleaned up correctly, and is usually reserved for objects that wrap unmanaged resources, such as unmanaged handles etc that won't get garbage collected.
It is rare indeed to write a finalizer. Fortunately (and unlike
IDisposable
), finalizers don't need to be propagated; so if you have aClassA
with a finalizer, and aClassB
which wrapsClassA
, thenClassB
does not need a finalizer - but quite likely bothClassA
andClassB
would implementIDisposable
.For managed code,
IDisposable
is usually sufficient. Even if you don't clean up correctly, eventually the managed objects will get collected (assuming they are released).终结器仅用于释放非托管资源,例如 GDI 位图句柄。 如果您不分配任何非托管资源,则不需要终结器。 一般来说,接触终结器中的任何托管对象都是一个坏主意,因为无法保证终结的顺序。
使用终结器的另一种有用技术是在应用程序需要时断言已调用 Dispose。 这可以帮助捕获 DEBUG 构建中的编码错误:
Finalizers are only for freeing unmanaged resources like GDI bitmap handles for example. If you don't allocate any unmanaged resources then you don't need finalizers. In general it's a bad idea to touch any managed object in a finalizer because the order of finalization is not guaranteed.
One other useful technique using a finalizer is to assert that Dispose has been called when the application is required to do so. This can help catch coding errors in a DEBUG build:
终结器是一种释放不受垃圾收集器控制的资源的机制,例如非托管句柄。 虽然
Dispose
可能会执行此操作,但不能保证消费者会调用它。Finalizers are meant as a mechanism to release resources not controlled by garbage collector, like an unmanaged handle. While
Dispose
might do it, it isn't guaranteed that the consumer will call it.终结器用于清理未处理的资源。
IE 中,没有什么强制要求您必须调用 Dispose(),但终结器会由垃圾收集器自动调用。
不应依赖此功能,因为无法保证垃圾收集何时(或是否)到达您的对象。
Finalizers are for cleaning up resources if they were not disposed.
IE, nothing enforces that you ever call Dispose(), but Finalizers are called automatically by the garbage collector.
This functionality should not be relied upon, as there is no guarantee when (or if) garbage collection will get to your object.
维基百科说:
则很可能会出现内存泄漏,因为无法保证所有者实际上会调用 Dispose()。
MS 本身建议您在实现者中编写类似的内容:
就个人而言,我无法忍受复制粘贴,因此我倾向于将其包装在抽象类中以供重用。
Wikipedia says:
And if you're not using a finaliser when you're writing IDisposables you've quite possibly got memory leaks, because there's no guarantee an owner is actually going to call Dispose().
MS themselves recommend you write something similar to this into your implementers:
Personally, I can't stand the copy-paste so I tend to wrap that in an abstract class for reuse.