何时实施IDisposable的最佳做法是什么?
如果在类中有一个托管对象,那么实现它是最好的经验法则,还是依赖于对象是在类中创建还是只是传入?我是否也应该为没有托管对象的类做这件事?
答案 0 :(得分:28)
如果您指的是非托管对象,那么只要您在班级中处理一个或多个非托管资源,就应该实施它。当您可能自己持有IDisposable的对象时,您也应该使用该模式,并确保在您的类处理时丢弃它们。
(同意这个问题已经被问过足够多的时间,如果要打印一台小型打印机的墨水......)
答案 1 :(得分:12)
虽然每个人都提到(非托管)资源,但我还有另外一件事要做:当我需要消除事件处理程序连接时,我会使用它,否则会阻止类超出范围并被垃圾收集。
作为一个例子,我有一个服务被注入到子视图中,该子视图将订阅服务上的各种异步完成类型事件。该子视图的所有者不知道具体类型是什么,它只是将其作为接口。该服务可能会在未来的某个任意点超出范围,我不希望它不被GC所左右。在删除该子视图后,所有者将调用Dispose来为其提供解除任何事件处理程序的机会。这是一个有点人为的(非常伪代码)示例,请注意子视图的接口如何实现IDisposable
。
public class OwnerView {
public OwnerView() {
_childView = new ChildView(myServiceReference);
}
public void CloseChildView() {
if (childView != null) {
_childView.Close();
_childView.Dispose();
}
_childView = null;
}
private IChildView _childView;
}
public class ChildView : IChildView {
public ChildView(MyService serviceRef) {
_serviceRef = serviceRef;
_serviceRef.GetSettingsAsyncFinished += new EventHandler(someEventHandler);
}
public void IDisposable.Dispose() {
_serviceRef -= someEventHandler;
}
private MyService _serviceRef;
}
public interface IChildView : IDisposable {
void DoSomething();
... etc ...
}
关于其他人在SO上有更多权威性评论,例如Do event handlers stop garbage collection from occuring?和Garbage collection when using anonymous delegates for event handling。您可能还想查看此codeproject文章。
答案 2 :(得分:6)
当您的类在您使用完毕后拥有要释放的资源时,您应该实现IDisposable。
答案 3 :(得分:6)
当您的类包含非托管对象,资源,打开的文件或数据库对象时,您需要实现IDisposable
。
答案 4 :(得分:6)
我认为the docs非常清楚IDisposable有什么用处。
此界面的主要用途是 释放非托管资源。该 垃圾收集器自动 释放分配给a的内存 当该对象为no时,为托管对象 使用时间更长但事实并非如此 可以预测什么时候垃圾 收集将发生。此外, 垃圾收集器不知道 非托管资源,如窗口 处理,或打开文件和流。
它甚至有一个例子。在该示例中,实现IDisposable
的类包含句柄。不再使用时,需要释放句柄。这是在Dispose()
方法中完成的。因此,该类的用户看到它实现了IDisposable
并且知道在不再需要该类时需要明确地处理该类(因此可以释放句柄)。最佳实践(即规则),当不再需要实例时,您应始终在Dispose()
个实例上调用IDisosable
。
答案 5 :(得分:0)
如果它具有需要处理的属性。