IDisposable :: Dispose()应该是虚拟的

时间:2014-03-04 20:33:11

标签: c# .net dispose idisposable virtual-functions

说SomeDisposable的工厂实际上是创建/返回一种看门狗Wrapper

public class Wrapper : SomeDisposable
{
    public new /*:(*/ Dispose() { ... };
}

并且调用者使用类似

using (SomeDisposable sd = SomeDisposableFactory.Create(...))
{
} // Wrapper.Dispose() never called.

永远不会调用Wrapper.Dispose()。如果Dispose()是虚拟的,则会调用Wrapper.Dispose()

IDisposable接口并不保证其他最佳实践方法virtual Dispose(bool)实际存在或强制要么是虚拟的,因此通常不能依赖它(它只是推荐的模式)。接口当前不允许对虚拟约束。

没有制定推荐的Dispose()模式虚拟有哪些优点和缺点可以解决这个特殊的困境。 C#是否允许通过接口强制虚拟方法(因为抽象类不像合约定义那样受欢迎)。

2 个答案:

答案 0 :(得分:2)

没有。该模式实际上表示Dispose()(非虚拟)应该调用protected virtual void Dispose(bool)方法。这可以保证基类Dispose调用可以正确地传递层次结构。

这在IDisposable的文档中有详细说明:

  • 它应该提供一个公共的非虚拟Dispose()方法和一个受保护的虚拟Dispose(布尔处理)方法。
  • Dispose()方法必须调用Dispose(true)并且应该禁止完成性能。
  • 基本类型不应包含任何终结器。

答案 1 :(得分:0)

这已经解决了。

sealed的一次性类型应使用公共dispose pattern

public class DisposableResourceHolder : IDisposable
{
    private SafeHandle resource; // handle to a resource

    public DisposableResourceHolder()
    {
        this.resource = ... // allocates the resource
    }

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

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // dispose managed resources.
            if (resource != null) resource.Dispose();
        }

        // free unmanaged resources.
    }
}