2016-05-31 194 views
1

我编写了一个继承DbConnection的类,但我并不完全理解它为什么会像它那样工作。为什么我需要我需要在子类中实现IDisposable()

起初,我有这样的:

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

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

的Close()方法不叫了,我们可以看到连接停留在MySQL服务器上。


现在我都这样了,它的工作原理(它真的关闭了连接,服务器就OK):

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类并覆盖关闭()方法不起作用?

+0

Dispose or Close?因为Dispose方法的内容已经存在 –

回答

1

您可以在reference sourceDbConnection看不重写Dispose,所以Dispose不会打电话Close

DbConnection继承自Component,这是执行IDisposable的地方。您可以从reference sourceDispose(bool disposing)方法是virtual看,所以你应该重写:

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

有些人可能会认为'DbConnection'中有一个“bug”,或者至少在[documentation](https://msdn.microsoft.com/en-us/library /system.data.common.dbconnection.close(v=vs.110).aspx):“...通过调用'Close'或'Dispose'来关闭连接,这在功能上是等同的。” - 但正如我们所看到的那样,不能保证继承类将保持该函数的等价性,当它很容易被创建时(至少通过“继承者的注释”或通过明确地编码该共同依赖)。 –

+0

谢谢我看到那里的逻辑。这很令人困惑,像[this](http://stackoverflow.com/questions/5243398/will-a-using-block-close-a-database-connection)显示了一个简单的使用()! –

+0

@MickaelV。这是特别令人困惑的,因为(如达米恩指出的)文件表明它也可以。但是,对链接问题的回答的评论是有效的:*实际上,我怀疑有任何DBConnection实现不会覆盖Dispose并关闭任何连接*。你只注意到这一点,因为你从基类继承。 –

0

using statement要求在该块结束Dispose方法。

由于DbConnection也实现了IDisposable接口,因此第一个片段中的using块将调用继承的Dispose方法。

连接保持活着可能是因为你重写了Close函数,但我不确定在这,请纠正我,如果我错了。

相关问题