有很多关于.Net的书籍和文章都描述了如何实现IDisposable接口,但是几乎每一篇实现的都不完全一样,这里将几个主要的实现进行合并,试图找出能够适应绝大多数条件的实现方法。
实现代码
1
namespace Disposable
2
}
2
分析
Dispose()方法用于显式的释放资源,可以在代码中直接调用,或者使用using语句间接调用。GC.SuppressFinalize告诉GC在垃圾回收时,不需要调用析构函数,可以提高垃圾回收的效率。
Close()方法与Dispose()作用相同,只是为了适应某些有Open方法的类,Open/Close相互对应比较符合一般习惯。
析构函数用于在垃圾回收的时候释放资源。如果用户没有/忘记在使用之后释放资源,CLR会在垃圾回收的时候调用此函数。虽然资源较晚被释放,但总是好于不释放。
Dispose(bool)是真正释放资源的地方,参数disposing表明是用户主动释放资源还是在垃圾回收时释放。当用户主动释放资源时,由于此对象的成员中,某些托管资源持有非托管资源,因此需要释放这些托管资源,如果这些托管资源实现了IDisposable,调用Dispose()即可。在垃圾回收时,由于无法确定这些托管资源是否已经被回收了,因此不要试图释放托管资源,GC会释放这些资源的。如果多次调用Dispose(bool)会有副作用,则需要添加disposed变量来判断是否已经释放了资源。如果对象可能会在多线程环境中使用,需要加锁防止同步问题。
最后,如果该类有派生类的话,要在派生类中override父类的Dispose(bool)方法,并在释放资源后调用父类的Dispose(bool),以正确释放父类的资源。