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

.net 如何在继承自另一个一次性类的类中实现一次性模式?,.net,design-patterns,idisposable,.net,Design Patterns,Idisposable,我经常在引用少量资源的简单类中使用一次性模式,但我从未在继承自另一个一次性类的类上实现过此模式,我开始对如何释放整个资源感到有点困惑 我从一个小示例代码开始: public class Tracer : IDisposable { bool disposed; FileStream fileStream; public Tracer() { //Some fileStream initialization } public vo

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

我从一个小示例代码开始:

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类中实现一次性模式,以确保当我处理它的实例时,它将同时处理继承类和基类中的资源


谢谢。

继承的类ServiceWrapper继承自实现IDisposable的类,因此SerieWrapper也实现IDisposable。为了证明这一点,我们创建了ServiceWrapper的一个实例。您将发现(使用intellisense)它也有一个Dispose()方法

我从两个方面看到了这一点:

  • 在派生类重写Dispose(bool disposing)中,清理您的内容,然后调用基类Dispose(bool disposing)。这里的问题是基类已经有了disposed gate变量和需要复制的检查

  • 创建一个受保护的清理方法,该方法在基类调用中进行Dispose(bool disposing),以实际执行清理。派生类可以重写它,进行清理,并调用基类清理方法。这使得基类中所有已处理的检查都不必复制


  • 请看Davy Brion的这篇博文:


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

    您遇到了一些问题,首先您没有定义终结器,但您调用了GC.Suppressfinalizer。 此外,您使用错误的方法设置了dispose,而且dispose不是线程安全的

    我使用了一个实现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);
                }
            }
        }
    }
    

    是的,我知道,但问题是它将在ServiceWrapper类内调用Dispose(bool disposing)方法,因此不会释放基类中的资源。如果我在继承类中的Dispose处调用base.Dispose()方法,我将遇到堆栈溢出问题。第一个解决方案似乎很好,但许多指南都警告了这种用法。disposing布尔函数用于通知Dispose()方法已调用disposing。在这里,我们不能说事实并非如此,但这是间接完成的。我终于找到了一条代码分析规则,它为这种情况定义了一条精确的准则:这条准则完全符合您的第一个解决方案。感谢本文。这是达德曼提出的第二种解决方案的一个很好的例子。我想我会选择这种方式,下次我将不得不做一次性课程。它更容易实现。再次感谢。