如何在继承自另一个一次性类的类中实现一次性模式?

时间:2010-04-03 15:01:19

标签: .net design-patterns idisposable

我经常在引用少量资源的简单类中使用一次性模式,但我从来没有必要在继承自另一个一次性类的类上实现这个模式,我开始对如何释放这个模式感到困惑整个资源。

我从一些示例代码开始:

public class Tracer : IDisposable
{
    bool disposed;
    FileStream fileStream;

    public Tracer()
    {
        //Some fileStream initialization
    }

    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                if (fileStream != null)
                {
                    fileStream.Dispose();
                } 
            }

            disposed = true; 
        }
    }
}

public class ServiceWrapper : Tracer
{
    bool disposed;
    ServiceHost serviceHost;

    //Some properties

    public ServiceWrapper ()
    {
        //Some serviceHost initialization
    }

    //protected override void Dispose(bool disposing)
    //{
    //    if (!disposed)
    //    {
    //        if (disposing)
    //        {
    //            if (serviceHost != null)
    //            {
    //                serviceHost.Close();
    //            } 
    //        }

    //        disposed = true;
    //    }
    //}
}

我真正的问题是:如何在我的ServiceWrapper类中实现一次性模式,以确保当我处理它的实例时,它将在继承类和基类中处理资源?

感谢。

4 个答案:

答案 0 :(得分:3)

我已经看到过这方面的几个方面:

  1. 在派生类中重写Dispose(bool disposing),清理你的东西,然后调用基类Dispose(bool disposing)。这里的问题是基类已经具有已处理的门变量并检查是否需要复制。

  2. 创建一个受保护的Cleanup方法,在基类调用中Dispose(bool disposing)实际进行清理。派生类可以覆盖它,进行清理,并调用基类的Cleanup方法。这使得基类中的所有已处理的检查都不需要复制。

答案 1 :(得分:2)

你有一些问题首先你没有定义终结器但你调用GC.Suppressfinalizer。 你设置错误的方法,并且你的处置不是线程安全的。

我使用了一个实现IDispose的基类处理类以及其他一些辅助方法。

public class Disposable : IDisposable
{
    private object _lock = new object();

    ~Disposable()
    {
        try
        {
            Dispose(false);
        }
        catch
        {

        }
    }

    protected void ThrowIfDisposed()
    {
        if (IsDisposed)
        {
            throw new ObjectDisposedException(GetType().FullName);
        }
    }

    public bool IsDisposed { get; private set; }

    protected virtual void Dispose(bool disposing)
    {

    }

    public void Dispose()
    {
        lock (_lock)
        {
            if (!IsDisposed)
            {
                Dispose(true);
                IsDisposed = true;
                GC.SuppressFinalize(this);
            }
        }
    }
}

答案 2 :(得分:1)

看看Davy Brion撰写的这篇博客文章:http://davybrion.com/blog/2008/06/disposing-of-the-idisposable-implementation/

它为父类添加了一些额外的代码,但在子类中进行适当的清理变得相当简单。

答案 3 :(得分:0)

继承的类ServiceWrapper继承自实现IDisposable的类,因此SericeWrapper也实现了IDisposable。为了证明,新建一个ServiceWrapper实例。你会发现(使用intellisense)它也有Dispose()方法。