有终结器但没有 IDisposable 的单例

2023-12-20

这是我从“CLR via C#”、“Effective C#”和其他资源中对 IDisposable 和终结器的理解:

  • IDisposable 用于确定性地清理托管和非托管资源。
  • 负责非托管资源(例如文件句柄)的类应该实现 IDisposable 并提供终结器,以保证即使客户端代码没有在实例上调用 Dispose(),它们也会被清理。
  • 仅负责托管资源的类永远不应该实现终结器。
  • 如果您有终结器,那么您必须实现 IDisposable(这允许客户端代码执行正确的操作并调用 Dispose(),而终结器可以防止在忘记时泄漏资源)。

虽然我理解并同意上述所有内容的原因,但在一种情况下,我认为打破这些规则是有意义的:负责非托管资源的单例类(例如提供对特定文件的单点访问) )。

我相信在单例上使用 Dispose() 方法总是错误的,因为单例实例应该在应用程序的生命周期内存在,如果任何客户端代码调用 Dispose() 那么你就会被塞满。但是,您需要一个终结器,以便在卸载应用程序时终结器可以清理非托管资源。

因此,在我看来,拥有一个带有未实现 IDisposable 的终结器的单例类是一件合理的事情,但这种类型的设计与我所理解的最佳实践背道而驰。

这是一个合理的做法吗?如果不,为什么不呢?更好的选择是什么?


我首先要提到的是,面向对象的设计模式及其后果并不总是影响每个语言决策,即使在面向对象的语言中也是如此。您当然可以找到用一种语言(Smalltalk)而不是另一种语言(C++)更容易实现的经典设计模式。

话虽如此,我不确定我是否同意单例实例只能在应用程序结束时处理的前提。我读过的设计模式描述中没有任何内容辛格尔顿 http://www.dofactory.com/Patterns/PatternSingleton.aspx (or 设计模式:可重用的面向对象软件的元素 https://rads.stackoverflow.com/amzn/click/com/0201633612)将此作为此模式的属性提及。单例应该确保该类在任何一个时刻都只存在一个实例;这并不意味着只要应用程序存在它就必须存在。

我有一种感觉,在实践中,应用程序生命周期的大部分时间里确实存在许多单例。但是,请考虑一个使用 TCP 连接与服务器通信但也可以以断开连接模式存在的应用程序。连接时,您需要一个单例来维护连接信息和连接状态。一旦断开连接,您可能希望保留相同的单例 - 或者您可以丢弃该单例。虽然有些人可能会认为保留单例更有意义(我什至可能是其中之一),但设计模式本身并没有什么可以阻止您处理它 - 如果重新建立连接,则可以实例化单例再说一次,因为当时不存在它的实例。

换句话说,您可以创建单例具有 IDisposable 是合乎逻辑的场景。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有终结器但没有 IDisposable 的单例 的相关文章