【问题标题】:If Dispose(bool) is overridden, will resources still be disposed?如果 Dispose(bool) 被覆盖,资源还会被释放吗?
【发布时间】:2014-07-09 20:47:52
【问题描述】:

参考:http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx

在这个 MSDN 示例中,如果在子类中重写了 Dispose(bool),是否会执行该基类中的 Dispose(bool) 代码? IE。 resource.Dispose() 会被调用吗?子类需要调用base.Dispose(true)吗?

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){
            if (resource!= null) resource.Dispose();
        }
    }
}

【问题讨论】:

  • 当然。当你重写一个方法时,你需要调用基类来执行它。
  • 这是一个完全错误的非常标准的例子。实现该模式没有意义,该类没有终结器,也没有继承强制重写 Disposable(bool) 的基类。当 disposing 为假时,您总是可以通过无所事事来判断。
  • 正如@Hans 所说,这种模式在这里不合适。有些人建议实现该模式,以防派生类拥有非托管资源——这完全是垃圾。派生类可以重新实现IDisposable,添加终结器,并提供virtual void Dispose(bool disposing) { if (disposing) { base.Dispose(); } } 基子对象在许多方面与成员子对象相似,包括在释放完整对象时应调用其Dispose() 方法。
  • (但不要在任何非最终类中显式实现IDisposable.Dispose(),因为这会阻止任何派生类调用base.Dispose()
  • @BenVoigt:使用密封的外部可调用Dispose 方法1 链接到虚拟方法1 的一个优点是它允许在对象静止时插入基类逻辑有效的。例如,如果基类附加了异步事件处理程序,它可以使用sealed dispose 方法安全地禁用它们并等待挂起的调用完成,然后派生类对象开始自行分解。

标签: c# .net idisposable


【解决方案1】:

是的,覆盖Dispose() 的类调用base.Dispose() 是标准的。如果一个类重写了Dispose,那么它的基类只有在被显式调用时才会执行它的实现。如果您的覆盖不遵循基类,那么您实际上已经承担了它的职责——这通常是不可取的。

在您的实现中以try/finally 块的形式添加错误处理也是值得的。使用finally 块调用基本Dispose 方法;这可以防止您的实现中的异常阻止其基类被释放。


CA2215: Dispose methods should call base class dispose(以下文字来自此来源)

原因

实现 System.IDisposable 的类型继承自同样实现 IDisposable 的类型。继承类型的 Dispose 方法不调用父类型的 Dispose 方法。

规则说明

如果一个类型继承自一次性类型,它必须从它自己的 Dispose 方法中调用基类型的 Dispose 方法。调用基类型方法 Dispose 可确保释放基类型创建的所有资源。

如何解决违规问题

要修复违反此规则的行为,请在 Dispose 方法中调用 base.Dispose。

何时取消警告

如果对 base.Dispose 的调用发生在比规则检查更深的调用级别,则可以安全地禁止来自该规则的警告。

【讨论】:

    猜你喜欢
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多