gpt4 book ai didi

c# - 具有终结器但不是 IDisposable 的单例

转载 作者:可可西里 更新时间:2023-11-01 07:46:02 26 4
gpt4 key购买 nike

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

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

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

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

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

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

最佳答案

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

话虽这么说,但我不确定我是否同意单例实例只应在应用程序结束时处理的前提。我为 Singleton 阅读的设计模式描述中没有任何内容(或 Design Patterns: Elements of reusable Object-Oriented Software )将此作为此模式的属性提及。单例应确保在任何时刻只存在该类的一个实例;这并不意味着只要应用程序存在,它就必须存在。

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

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

关于c# - 具有终结器但不是 IDisposable 的单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/463716/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com