以下是我从《CLR via C#》、《Effective C#》和其他资源中了解到有关IDisposable和finalizers的内容:
- IDisposable用于确定性地清理托管和非托管资源。
- 负责非托管资源(如文件句柄)的类应实现IDisposable,并提供finalizer以确保即使客户端代码不调用实例上的Dispose(),它们也会被清理。
- 仅负责托管资源的类永远不应该实现finalizer。
- 如果你有一个finalizer,则必须实现IDisposable(这允许客户端代码正确地调用Dispose(),而finalizer则可以防止资源泄漏,即使客户端代码忘记调用Dispose())。
虽然我理解并同意上述所有观点的论据,但有一种场景,我认为打破这些规则是有道理的:一个负责非托管资源的单例类(例如提供对特定文件的单一访问点)。
我认为在单例上有Dispose()方法总是不妥当的,因为单例实例应该在应用程序的生命周期内存在,如果任何客户端代码调用了Dispose(),那么你就会遇到麻烦。然而,你需要一个finalizer,以便在卸载应用程序时,finalizer可以清理非托管资源。
因此,对于一个不实现IDisposable但拥有finalizer的单例类来说,这似乎是合理的一件事情。然而,这种设计类型与我理解的最佳实践相反。
这是一个合理的方法吗?如果不是,为什么不是,并且有什么更好的替代方案?