我应该在 IDisposable 和 Finalize 上实现 GC.SupressFinalize 吗?
我的新客户处的代码审查清单包含以下内容 -
实现 Dispose 和 Finalize 的类应该在 Dispose 实现中调用 GC.SupressFinalize
为什么?
难道它不应该被理解为实现 IDisposable 接口的类应该在 Dispose 实现中调用 GC.SupressFinalize 吗?
或者我错过了一些愚蠢的事情?
The code review checklist in my new client place has the following -
Class implementing Dispose and Finalize should have a call to GC.SupressFinalize in Dispose implementation
Why?
Should it not read as Class implementing IDisposable interface should have a call to GC.SupressFinalize in the Dispose implementation?
Or Am I missing something silly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您忽略了这样一个事实:并非每个一次性类都需要终结器 - 事实上,很少有人这样做,特别是由于 .NET 2.0 的
SafeHandle
类型。如果没有终结器,为什么需要调用SuppressFinalize
?You're missing the fact that not every disposable class needs a finalizer - in fact, very few do, particularly due to .NET 2.0's
SafeHandle
type. If there's no finalizer, why would you need to callSuppressFinalize
?这是准确的。如果 Dispose(bool) 方法完成了它的工作,那么就不再需要让终结器再次执行它。调用 GC.SuppressFinalize() 是一种优化,您可以阻止 .NET 费心调用不执行任何操作的终结器。
我注意到您用大写的 C 编写了 Class。这暗示您正在用 VB.NET 编写代码。请注意,在 99.99% 的情况下,IDE 都会执行错误。一旦您在输入“Implements IDisposable”后按下 Enter,它就会插入错误代码:
Yuck。这是终结器的样板实现,顺便说一句,在 MSDN 库中有详细记录。这是错误的。实际需要终结器的情况极为罕见,.NET 类已经自行处理了。如果您确实使用操作系统句柄,那么您应该使用 SafeHandle 派生类之一。或者编写您自己的包装器。
将其编辑回此:
It's accurate. If the Dispose(bool) method did its job then there is no longer any point to let the finalizer do it again. Calling GC.SuppressFinalize() is an optimization, you stop .NET from bothering to call a finalizer that does nothing.
I noticed that you wrote Class with a capital C. That's a hint that you are writing your code in VB.NET. Watch out, the IDE does the wrong thing in 99.99% of all cases. As soon as you press Enter after typing "Implements IDisposable", it inserts the wrong code:
Yuck. That's the boilerplate implementation of a finalizer, well documented in the MSDN Library btw. It's wrong. It is extremely rare to actually need a finalizer, the .NET classes already take care of it themselves. If you really do use an operating system handle then you should use one of the SafeHandle derived classes. Or write your own wrapper.
Edit it back to this: