这是我了解了IDisposable和终结从“通过C#CLR”,“有效的C#”和其他资源:辛格尔顿与终结,但不是IDisposable的
- IDisposable的是清理托管和非托管资源确定性。
- 负责非托管资源(例如文件句柄)的类应该实现IDisposable并提供一个终结器,以确保即使客户端代码不调用实例上的Dispose(),它们也会被清除。
- 只负责管理资源的类不应该实现终结器。
- 如果你有一个终结器,那么你必须实现IDisposable(这允许客户端代码做正确的事,并调用Dispose(),而终结器可以防止漏掉的资源,如果他们忘记)。
虽然我理解推理,并与所有上述的同意,有一个场景,我觉得很有道理,打破这些规则:一个单身类,负责非托管资源(如提供单访问特定文件的点)。
我相信在单例中有一个Dispose()方法总是错误的,因为单例实例应该活在应用程序的整个生命周期中,并且如果任何客户端代码调用Dispose(),那么你就塞满了。但是,您需要一个终结器,以便卸载该应用程序时,终结器可以清理非托管资源。
因此,使用不带实现IDisposable的终结器的单例类似乎是合理的事情,但这种类型的设计与我所了解的最佳实践相反。
这是一个合理的方法吗?如果不是的话,为什么不,优越的选择是什么?
事实是,如果你可以想象你的对象在应用程序的生命周期中被替换的原因,该对象不能合法地成为单例。至于为什么......说我抓住Singleton并将它传递给需要它的东西(原因,你知道,依赖注入是一件好事)。然后某个地方决定取代它。现在有*两个单身人士*(我已经过去的旧单身人士和新单身人士)。这种可能性违反了Singleton的整个定义 - 也就是说,代码总是只能看到一个实例。 – cHao 2012-01-30 22:23:04
所以,首先,圣洁的老人回答蝙蝠侠。 其次,你的例子似乎没有道理。如果你将一个单例的实例传递给一个对象,然后其他对象决定它需要单例,那么该模式允许 - 它应该得到一个引用回到当前在内存中的对象。我所做的一点是,这种模式并不妨碍你处理这个物体。在这种情况下,使用你的例子,如果对象被丢弃,那么单个实例应该不再存在,所以当一个不同的对象请求单例时,它应该得到一个新的实例。 – 2012-02-09 23:34:46
如果对象被丢弃,实例*仍然存在 - 任何在它被丢弃之前获得它的实例仍然会存在。所以它显然不能被GCed,但它现在无法使用。在多线程环境下考虑该声明的后果。像`Singleton.getInstance()。doStuff()`这样的表达式不再是线程安全的,*即使getInstance和doStuff都是*。一个线程可以在两个调用之间出现,并处理我们刚获得的实例。这甚至假设你是神话般的每个人总是调用``getInstance`场景。 – cHao 2012-02-10 04:40:49