2016-05-31 3 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.


Теперь у меня есть это, и работает (это действительно закрывает соединение, а сервер ОК):

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 уже существует –

ответ

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(); 
} 
+0

Некоторые могут утверждать, что в 'DbConnection' есть ошибка, или, по крайней мере, в ее [документации] (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, блок использования в первом фрагменте вызывает унаследованный метод Dispose.

Соединение остается живым, возможно, потому, что вы переопределяете функцию Close, но я не уверен в этом, пожалуйста, исправьте меня, если я ошибаюсь.

 Смежные вопросы

  • Нет связанных вопросов^_^