在C#中正确配置对象层次结构

时间:2012-10-20 10:16:21

标签: c# .net dispose idisposable finalize

我正在开发一个项目,其中某个类层次结构实现了IDisposable。

有些类还实现了Finalize方法(~MyClass())

一般来说,它看起来像这样:

public class BaseClass : IDisposable
{
}

public class SomeClass : BaseClass
{
    ~SomeClass()
    {
        Dispose();
    }

    Dispose()
    {
        // Do some stuff.
        base.Dispose();
    }
}

public class AnoterClass : SomeClass
{
    ~AnoterClass()
    {
        Dispose();
    }

    Dispose()
    {
        // Do some stuff.
        base.Dispose();
    }
}

我想知道处理Dispose调用的正确方法是什么,因为看起来这些对象是通过调用Dispose()来处理的,后来因为Finalize方法被调用而崩溃了。

最好是在层次结构中的最低级别保留一个标志(处理受保护的bool),并在类层次结构的每个级别检查它吗?

我发现每个可能的解决方案都需要一些代码重复,这不是我想要的。

2 个答案:

答案 0 :(得分:5)

如果手动处理对象,则需要取消终结。

要遵循的模式是here

编辑:

我认为你只需要在类层次结构的特定级别实现,如果你有新的东西要在那个级别进行处理,否则我相信基类中的处理将完成你需要的所有事情。如果您在任何特定类中的实现只调用base.Dispose(disposing),则不需要它,如果必须执行一些干净的uop,则调用base.Dispose()然后您需要它。

如你所示,拥有受保护的旗帜应该没问题。

答案 1 :(得分:4)

如果您的基类实现了standard IDisposable pattern,那么您需要做的就是将Dispose(bool disposing)覆盖添加到自己拥有IDisposable或非托管资源的每个派生类:

protected override void Dispose(bool disposing)
{
    try
    {
        if (disposing)
        {
            // Release managed resources
        }
        // Release unmanaged resources
    }
    finally
    {
        base.Dispose(disposing);
    }
}

您不应在任何派生类中实现终结器。

当然,层次结构中没有自己的IDisposable资源的任何类都不需要这种覆盖。