IDisposable究竟需要什么?

可能重复:
正确使用IDisposable接口

我试图从书籍,互联网和计算器上找到我的问题的实际答案,但迄今为止没有任何帮助我,所以希望我可以将我的问题准确无误地讲出来。

总的来说,我总是发现如何释放内存的基本用法,这是近似的。 如下所示,我确实了解代码本身:

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);
    }
}

它使这些方法的工作方式具有完全意义。 但现在我的问题是:为什么我们需要基类IDisposable? 在这个代码示例中,我们定义了一个名为Dispose()的方法。 当我在处处看到这个方法是IDisposable的一部分的时候,但是我们刚才在MyClass定义了这个方法,如果我们没有实现基类IDisposable或者我错了这个假设,那么这个代码仍然可以工作?

我并不是C#的全新人物,但对我来说还有很多东西需要学习,所以希望有人能够带领我朝着正确的方向前进。 我检查了另一个帖子,但是找不到它,所以如果它确实存在,它确实回答我的问题,请带我到那里,我会删除这篇文章。


你是对的,作为你的析构函数~MyClass调用Dispose ,看起来没有必要使用接口IDisposable

Dispose不仅仅由析构函数调用。 当你想要处理非托管资源时,你可以在代码中自己调用它。 这是需要的,因为你不知道何时调用析构函数(取决于垃圾收集器)。

最后, IDisposable.Dispose当你使用一个被称为using

using(MyDisposableClass myObject = new MyDisposableClass())
{
    // My Code
}

相当于:

MyDisposableClass myObject = new MyDisposableClass();
try
{
    // My Code
}
finally
{
    myObject.Dispose();
}

IDisposable.Dispose的实际实现调用Dispose(bool)的基类实现。 如果从这个类继承的任何人现在有以下任务,他们也需要处理:

public override Dispose(bool disposing)
{
    base.Dispose(disposing);
    //my disposal code
}

使用这种广为人知的模式可以让继承者扩展处置代码而不会中断基类的处置。

通常情况下,如果您没有非托管资源来处理并且能够负担您班级的费用,您可以使用以下代码简化事宜:

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 
    //}
}

通过实现IDispose,您可以释放像“流”,句柄或数据库连接一样“持有”的资源。

从垃圾收集器调用Dispose(),基本上询问对象:“如果有什么东西你不再需要,但我不知道;现在释放它;清理!”

在某种意义上,与C ++中的析构函数相比

不同之处在于C ++析构函数会立即被调用,并进一步及时调用Dispose()。

在大多数情况下,你不需要实现它。 GC非常聪明,能够在90%的案例中找出如何释放已用资源。

但是例如:释放流使用的内存不会自动关闭流,并且释放数据库连接也不会关闭它。

通过实施Dispose,您可以在发布对象时关闭该文件:

internal class Something : IDisposable {
private Stream stream;

public void SomeMethod() {
    stream.Write("nskdns");
}

public void Dispose() {
    if (stream != null) {
        stream.Close();
    }
}

另外:实现IDispose使您有机会在using语句中使用该类:

public void Example() {
    using (var x = new Something())
    {
        x.SomeMethod();
    }
}

确保x在被GC释放时始终关闭使用的流。

然而,我更喜欢该类上的专用Close()方法,以允许显式关闭流而不依赖GC并调用Dispose()

链接地址: http://www.djcxy.com/p/54469.html

上一篇: What exactly is IDisposable needed for?

下一篇: The primary use of IDisposable interface