C#中IDispose接口的实现及为何这么实现详解

2019-12-30 19:45:14王振洲

这样IDisposable中的Dispose方法就变成了这样:


public void Dispose() 
{ 
 Dispose(true); //I am calling youfrom Dispose, it's safe 
} 

终结器就变成了这样…


~MyObject() 
{ 
 Dispose(false); //I am *not*calling you from Dispose, it's *not* safe 
} 

注意:你的类如果是从另一个类继承而来,那么你不要忘记去调用父类的Dispose方法


public Dispose() 
{ 
 try 
 { 
  Dispose(true); //true: safeto free managed resources 
 } 
 finally 
 { 
  base.Dispose(); 
 } 
} 

所有的一切看起来都已经很好了,除非,你想做的更好!

2.5、最完美的方法?

如果使用者手动调用了Dispose方法,这样,一切都被清空了。之后呢,因为你重写了Finalize方法,GC一定调用这个方法,它将会再一次调用Dispose方法!

这不仅是一种性能上的浪费,而且关键是在Dispose方法调用后,那些引用已经变成了垃圾,GC会调用这些垃圾引用!

解决的方法是通过在Dispose方法中调用GC.SuppressFinalize() 来阻止GC去调用Finalize方法


public void Dispose() 
{ 
 Dispose(true); //I am calling youfrom Dispose, it's safe 
 GC.SuppressFinalize(this); //Hey,GC: don't bother calling finalize later 
} 

这样,每一件事都照顾到了!

(注:其实可以将Dispose(bool disposing)方法变成虚函数,如果你的类被继承)

至此,我们一步一步实现了最好的IDisposable方法,现在回头去看看一开始的实现IDisposable接口教程,是不是一切的透彻了?

三、使用终结器还是Dispose方法释放非托管资源?

其实两种方法都可以,但是就像在一开始提到的,GC的垃圾回收时间不确定,对于那些你已经不需要的资源,还是尽快释放比较好,不应该总等着GC的垃圾回收,而且还有一个好处是,降低GC垃圾回收的时间,提高效率。何乐而不为呢?

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对ASPKU的支持。


注:相关教程知识阅读请移步到c#教程频道。