День сто девятнадцатый. #ВопросыНаСобеседовании

Самые часто задаваемые вопросы на собеседовании по C#

9. В чем разница между методами dispose и finalize в C#?

Мы использовали метод Dispose для удаления объектов в .NET. Для этой же цели мы также можем использовать метод Finalize. В чём же разница между ними?



Dispose

Сборщик мусора (GC) играет важную роль в управлении памятью в .NET, поэтому программист может сосредоточиться на функциональности приложения. Сборщик мусора отвечает за освобождение памяти (объектов), которая не используется приложением. Но у него есть ограничение: он может восстанавливать или освобождать только память, которая используется управляемыми ресурсами. Есть несколько ресурсов, которые GC не может высвободить, поскольку у них нет информации о том, как запросить память. Это такие ресурсы, как обработчики файлов, обработчики окон, сетевые сокеты, соединения с базой данных и т.д. Если ваше приложение использует эти ресурсы, то в его ответственности освобождать неуправляемые ресурсы. Например, если мы откроем файл в нашей программе и не закроем его после обработки, этот файл не будет доступен для других операций или использования другим приложением, т.к. они не смогут открыть или изменить этот файл. Для этого класс FileStream предоставляет метод Dispose. Мы должны вызвать этот метод после завершения обработки файла. В противном случае будет выброшено исключение "Access Denied or file is being used by other program" ("Доступ запрещен или файл используется другой программой").

Close или Dispose

Некоторые объекты предоставляют оба метода: и Close, и Dispose. Для потоковых классов (наследников Stream) оба служат одной цели. Метод Dispose вызывает метод Close внутри себя.

Тогда зачем нам метод Dispose в классе Stream? Наличие метода Dispose позволит вам написать приведенный ниже код и неявно вызвать метод Dispose, который, в конечном итоге, вызовет метод Close.

using(FileStream file = new FileStream("path", FileMode.Open, FileAccess.Read))

{

//Выполняем операции с файлом

}

Но в некоторых классах эти методы ведут себя немного по-разному. Например, класс Connection. Если вызывается метод Close, он отключается от базы данных и освобождает все ресурсы, используемые объектом подключения, а метод Open снова подключает его к базе данных без повторной инициализации объекта подключения. А метод Dispose полностью освобождает объект подключения, и его нельзя открыть, просто вызвав метод Open. Нам придется повторно инициализировать объект Connection.

Создание метода Dispose

Чтобы реализовать освобождение ресурса через метод Dispose для вашего пользовательского класса, вам нужно реализовать интерфейс IDisposable. Интерфейс IDisposable предоставляет метод Dispose, в котором будет написан код для освобождения неуправляемого ресурса.