2016-05-31 244 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函數,但我不確定在這,請糾正我,如果我錯了。

相關問題