答案 0 :(得分:3)
答案 1 :(得分:1)
好的,首先我要指出一些我对你的IStoppable建议感到不舒服的事情。
IStoppable引发事件已停止,消费者必须了解此情况并发布引用。这有点复杂,最坏的问题。消费者必须知道每个参考的位置,以便删除/重置参考。
你声称“......只是删除了大多数引用,没有任何东西被破坏。”这完全取决于实现IStoppable的对象及其用途。比如说,我的IStoppable对象是一个对象缓存。现在我忘记或忽略了这个事件,然后突然我正在使用不同的对象缓存作为世界其他地方...也许这没关系,也许不是。
事件是一种提供此类行为的可怕方式,因为异常证明难以处理。当第三个10个事件处理程序在IStoppable.Stopped事件中抛出异常时,这意味着什么?
我认为你试图表达的是一个可能由许多事物“拥有”并且可以被一个人强行释放的对象?在这种情况下,您可以考虑使用引用计数器模式,更像是旧式COM。当然,这也存在问题,但在管理世界中它们不是问题。
围绕对象的引用计数器的问题是您回到无效/未初始化对象的想法。解决此问题的一种可能方法是为引用计数器提供有效的“默认”实例(或工厂委托),以便在所有引用都已发布且有人仍想要实例时使用。
答案 2 :(得分:1)
我认为你对现代OO语言有误解;特别是范围和垃圾收集。
对象的生命周期受其范围的控制。范围是限于使用子句,方法,还是appdomain。
虽然您不一定“关心”对象的生命周期,但编译器会在它超出范围时立即将它放在垃圾收集的旁边。
你可以通过故意告诉垃圾收集器立即运行来加速这个过程,但这通常是毫无意义的练习,因为编译器会在最合适的时机优化代码。
如果您正在讨论多线程应用程序中的对象,那么这些对象已经公开了停止执行或以其他方式根据需要终止它们的机制。
这使我们无法管理资源。对于那些,包装器应该实现IDisposable。我会跳过谈论它,因为Reed Copsey已经很好地解决了这个问题。
答案 3 :(得分:0)
虽然有时Disposed事件(如Windows Forms使用的事件)很有用,但事件会增加一些开销。如果一个对象将保留它所拥有的所有IDisposable,直到它被处置(一般情况),最好保留List(Of IDisposable)并具有私有函数“T RegDisp< T>(T obj)其中T :IDisposable“将一个对象添加到一次性用品列表并返回它。而不是将字段设置为SomeDisposable,将其设置为RegDisp(SomeDisposable)。请注意,在VB中,如果所有构造函数调用都包含在工厂方法中,则可以在字段初始值设定项中安全地使用RegDisp(),但这不能在C#中完成。
顺便提一下,如果IDisposable的构造函数接受IDisposable作为参数,那么让它接受一个布尔值通常会有所帮助,该布尔值指示是否将传输该对象的所有权。如果可能拥有的IDisposable将在可变属性(例如PictureBox.Image)中公开,则属性本身应该是只读的,并使用接受所有权标志的setter方法。当对象拥有旧对象时调用set方法应该在设置新对象之前处理旧对象。使用这种方法将消除对Disposed事件的大部分需求。