【问题标题】:Why do I need I need to implement IDisposable() on a child class为什么我需要在子类上实现 IDisposable()
【发布时间】:2016-05-31 09:33:51
【问题描述】:

我编写了一个继承 DbConnection 的类,但我不完全理解它为什么会这样工作。

起初我有这个:

public class DatabaseConnection : DbConnection
{
    ... 
    public override void Close()
    {
        // Some stuff
    }   
    // No Dispose method
}

using(var db = new DatabaseConnection())
{
    // Some processing
}

没有调用 Close() 方法,我们可以看到连接停留在 MySQL 服务器上。


现在我有了这个,它可以工作了(它确实关闭了连接,服务器也正常):

public class DatabaseConnection : DbConnection, IDisposable
{
    ... 
    public override void Close()
    {
        // Some stuff
    }   

    public new void Dispose()
    {
        Close();
        base.Dispose();
        GC.SuppressFinalize(this);
    }
}

using(var db = new DatabaseConnection())
{
    // Some processing
}

为什么继承 DbConnection 类并覆盖 Close() 方法不起作用?

【问题讨论】:

  • 丢弃还是关闭?因为Dispose方法的内容已经有了

标签: c# idisposable dbconnection


【解决方案1】:

您可以在reference source 中看到DbConnection 不会覆盖Dispose,因此Dispose 不会调用Close

DbConnection 继承自 Component,这是 IDisposable 的实现所在。从reference source 可以看出,它的Dispose(bool disposing) 方法是virtual,所以你应该重写它:

protected override void Dispose(bool disposing)
{
    base.Dispose(disposing)
    Close();
}

【讨论】:

  • 有些人可能会争辩说DbConnection 中存在“错误”,或者至少在documentation 中存在“错误”:“...通过调用CloseDispose 关闭连接,这在功能上是等效的。” - 但正如我们所见,不能保证继承类将保持该功能等效性,而它本来可以很容易地做到这一点(至少通过“给继承者的注释”或通过显式编码这种相互依赖关系)。
  • 谢谢,我看到了那里的逻辑。这与 this 显示简单 using() 之类的所有问题都非常令人困惑!
  • @MickaelV。这尤其令人困惑,因为(正如 Damien 指出的那样)文档说它也是这样工作的。不过,对您的链接问题的答案的评论是有效的:实际上,我怀疑是否有任何 DBConnection 实现不会覆盖 Dispose 并关闭任何连接。您只是注意到这一点,因为您是从基类继承的。
【解决方案2】:

using statement 在块的末尾调用 Dispose 方法。

由于DbConnection也实现了IDisposable接口,所以第一个sn-p中的using块调用了继承的Dispose方法。

连接保持活跃可能是因为您覆盖了关闭功能,但我不确定,如果我错了,请纠正我。

【讨论】:

    猜你喜欢
    • 2020-03-23
    • 1970-01-01
    • 2011-01-30
    • 2012-07-04
    • 2012-01-19
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多