Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 微软';什么样的模式?_C#_Design Patterns_Idisposable - Fatal编程技术网

C# 微软';什么样的模式?

C# 微软';什么样的模式?,c#,design-patterns,idisposable,C#,Design Patterns,Idisposable,微软的建议是Dispose()和finalizer都应该调用虚拟的第三个方法Dispose(bool)。看起来是这样的: public class DisposeBase : IDisposable { private bool _Disposed = false; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~DisposeBa

微软的建议是Dispose()和finalizer都应该调用虚拟的第三个方法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;
        }
    }
}
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
}
派生类将重写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;
        }
    }
}
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
}
我想到的场景是,在一个框架中,您声明了一个抽象基类,该基类提供了一个接口和一些获取需要处理的资源的实现—因此是
IDisposable
接口。现在,扩展这个基类的客户机将被迫考虑如何处置其托管和非托管资源。在微软建议的模式中,人们可能会忘记它。请将名称
extensableResourceHandlerBase
看作一个占位符


在我看来,这将使从DisposeBase派生的客户端更容易实现其dispose方法。作为回答,其他人也这么认为。我能想到的唯一原因是,为什么微软的好人会像现在这样构建他们的模式,而不是将托管资源和非托管资源的处置分开。还有其他原因吗?非常感谢您的启发。

当Microsoft记录并推荐
Dispose
模式时,人们期望实现
IDisposable
的类通常会有一组资源,它们将在
Dispose
中清理,并在
Finalize
中清理;该模式是围绕这一期望设计的。实际上,除了记录调用
Dispose
的失败之外,应该重写
Finalize
的类只有那些直接从
对象继承的类。如果父类未重写
Finalize
的派生类将使用应在终结器中清理的非托管资源,则它不应重写
Finalize
本身,也不应直接保存非托管资源,而是将资源封装在专用于该目的的类的实例中。这将有助于避免许多奇怪和棘手的边缘情况,否则这些情况可能会随着包含托管和非托管资源混合的对象的终结而出现


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

我在这里写了一个关于将IDisposable实现置于层次结构基础的答案。您需要描述您的模式的好处。到目前为止,我看到需要实现2个函数,并担心链接虚拟2个函数而不是1个函数。。。还不确定是什么平衡了它的积极面。你们只得到一次继承权的机会,所以这对我来说是不可能的。此外,我想不出任何实际情况下派生类是“is-a DisposeBase”。DisposeBase类的全部目的是处置,因此派生类将完全以不同的方式处置自己。是的。我认为Liskov不会同意。@KeithPayne-原始示例是“模式”(在“我们建议您以这种方式在类中实现
IDispose
”)-它不使用基类-只是建议如何构造它(如果确实需要在层次结构中处理对象)。尚不清楚OP的建议为什么会是更好的模式(因为它更复杂…+1)。一个巨大且持续的混淆源是参数的命名-
disposing
。如果MS发布了名为
的参数的相同模式,而不是从finalizer调用
或类似的参数,则会更加清楚。但是现在已经太晚了。@KeithPayne改变这个名字会是一个突破性的改变吗?我想不出哪种情况会是这样。@Servy一点也不。MS在MSDN上发布了带有
disposing
的代码示例,此后,它一直按原样在生产代码中使用。这就像一条令人遗憾的推特——一旦它进入网络,你永远无法摆脱它@基思佩恩:如果我能改变一些模式代码,我会的。我认为,如果一个类将有一个
Disposed
标志,那么应该通过非虚拟
Dispose
处理程序中的
Interlocked
方法对其进行测试和设置。没有其他好方法可以拥有可重写的线程安全
Dispose
方法。由于每次调用
Dispose
时都必须创建一个对象(否则会处理什么?),因此
联锁的开销不应该是一个问题。@supercat-谢谢您的回答,但这不是我想要的。我编辑了这个问题,希望能让它更容易理解。很抱歉。不接受第一个答案可以吗?