微软处置模式结构的原因是什么?

S. *_*rws 2 c# design-patterns idisposable

微软建议的配置模式说Dispose()和终结器都应该调用虚拟的第三种方法Dispose(bool).所以它看起来像这样:

public class DisposeBase : IDisposable
{
    private bool _Disposed = false;

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

    ~DisposeBase()
    {
        Dispose(false);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_Disposed)
        {
            if (disposing)
            {
                /* Get rid of managed resources */
            }

            /* Get rid of unmanaged resources */

            _Disposed = true;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

派生类将覆盖Dispose(bool).我想重组它有点像这样:

public abstract class ExtendableResourceHandlerBase : IDisposable
{
    private bool _Disposed = false;

    /* private resources managed and unmanaged */

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

    ~DisposeBase()
    {
        Dispose(false);
    }

    private void Dispose(bool disposing)
    {
        if (!_Disposed)
        {
            if (disposing)
            {
                ManagedDispose();

                // Dispose of own managed resources
            }

            UnmanagedDispose();

            // Dispose of own unmanged resources

            _Disposed = true;
        }
    }

    protected abstract void ManagedDispose();

    protected abstract void UnmanagedDispose();

    protected abstract xxx ExtendMe(....)

    // other member functionality
}
Run Code Online (Sandbox Code Playgroud)

我想的是在一个框架中你要声明一个抽象基类,它提供了一个接口和一些实现,需要处理需要处理的资源 - 因此是IDisposable接口.现在,扩展此基类的客户也将被迫考虑处理其托管和非托管资源.对于来自微软的建议模式,人们可能会忘记它.请将该名称ExtendableResourceHandlerBase视为占位符.

在我看来,这将使得从DisposeBase派生的客户端更容易实现他们的dispose方法.而另一个问题的答案显示,其他人也这么认为.我可以想到为什么微软的好人建立他们现在的模式的唯一原因不是分割托管和非托管资源的处置.还有其他原因吗?非常感谢你的启发.

sup*_*cat 5

当Microsoft记录并推荐该Dispose模式时,预计实现的类IDisposable通常会有一组资源可以清理,Dispose而更小的集合可以清理Finalize; 这种模式是围绕着这种期望而设计的.在实践中,Finalize除了记录调用失败之外,为了任何目的而应该覆盖的唯一类Dispose是直接从中继承的类Object.如果其父级未覆盖的派生类Finalize将使用应在终结器中清除的非托管资源,则它不应覆盖Finalize自身,也不应直接保存非托管资源,而是将资源封装在专用于的类的实例中那个目的.这将有助于避免许多奇怪而棘手的边缘情况,否则这些边缘情况可能会导致对象的最终确定,这些对象包含托管和非托管资源的混合.

使用简单地链接到虚拟方法的接口方法是一个好主意,即使该protected void Dispose(bool)方法永远不会被调用,其参数不是true.如果受保护的虚拟方法是通过名称而不是通过无用的参数来区分的,那么模式可能会更清晰一些,但是有足够的人期望微软模式即使它不完美也可以使用它.