What exactly is IDisposable needed for?
Possible Duplicate:
Proper use of the IDisposable interface
我试图从书本、互联网和StackOverflow上找到我问题的真实答案,但到目前为止没有任何帮助,所以我希望我能准确地说出我的问题,使之有意义。
一般来说,我总是发现如何释放内存的基本用法相同,大致如下所示,我确实理解代码本身:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class MyClass : IDisposable { bool disposed = false; public void Dispose() { if (!disposed) { Dispose(true); GC.SuppressFinalize(this); disposed = true; } } protected virtual void Dispose(bool disposing) { if (disposing) { //free managed ressources } // free other ressources } ~MyClass() { Dispose(false); } } |
方法的工作方式是完全有意义的。但现在我的问题是:为什么我们需要可以识别的基类?在这个代码示例中,我们定义了一个名为
我对C并不完全陌生,但我还有很多东西要学,所以希望有人能引导我走上正确的方向。我查了另一篇文章,但找不到同样的问题,所以如果它确实存在并且回答了我的问题,请引导我到那里,我会删除这篇文章。
你说得对,正如你的析构函数
但是,
最后,当使用
1 2 3 4 |
相当于:
1 2 3 4 5 6 7 8 9 | MyDisposableClass myObject = new MyDisposableClass(); try { // My Code } finally { myObject.Dispose(); } |
实现IDispose为您提供了一个释放您"持有"的资源的地方,比如流、句柄或数据库连接。
Dispose()是从垃圾收集器调用的,基本上是询问对象:"如果您不再需要某些东西,但我无法确定;现在释放它;清理!"
在某种意义上,类似于C++中的析构函数
不同之处在于,C++析构函数在时间上被立即调用和处理()。
在大多数情况下,您不需要实现它。GC非常聪明,能够在90%的案例中找出如何释放已使用的资源。
但是,例如:释放流使用的内存不会自动关闭流和释放数据库连接也不会关闭它。
实现Dispose允许您在释放对象时关闭文件:
1 2 3 4 5 6 7 8 9 10 11 12 | internal class Something : IDisposable { private Stream stream; public void SomeMethod() { stream.Write("nskdns"); } public void Dispose() { if (stream != null) { stream.Close(); } } |
此外:实现IDispose使您有机会在using语句中使用类:
1 2 3 4 5 6 |
确保当GC释放已使用的流时,X总是将其关闭。
但是,我更喜欢类上的专用close()方法来允许显式关闭流,而不是依赖GC和调用Dispose()。
IDisposable.Dispose的实际实现调用Dispose(bool)的基类实现。从此类继承的任何人现在都具有以下任务,如果他们还需要释放:
1 2 3 4 5 | public override Dispose(bool disposing) { base.Dispose(disposing); //my disposal code } |
使用这种公认的模式,继承者可以在不破坏基类处置的情况下扩展处置代码。
通常,如果您没有要处理的非托管资源,并且能够密封类,则可以使用以下代码简化问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public sealed class SomeDisposable:IDisposable { public void Dispose() { //just go ahead and clean up //because we're sealed, no-one can ever break //this code via inheritance } //~SomeDisposable() //{ // if this is being called then it will be called // on all referenced and unrooted IDisposables too // If everything is managed, that means we've got nothing // left to clean up, so we can omit this Finalizer //} } |
它与c编译器的