В чем разница между деструктором и методом Dispose в C# и зачем нужны оба
Что проверяют
Понимаете ли вы, что один детерминирован, а другой нет, и знаете ли современную практику.
Как отвечать
Освобождение через специальный метод это детерминированное действие: вы или конструкция автоматического освобождения вызываете его в известный момент, сразу после того, как ресурс перестал быть нужен.
Финализатор, который по синтаксису выглядит как деструктор, вызывается сборщиком мусора в неизвестный момент. Гарантии, что он вообще будет вызван до завершения программы, нет.
Разница по последствиям:
- соединение с базой, файл, сокет должны освобождаться немедленно. Ожидание сборки мусора означает исчерпание пула соединений и заблокированные файлы;
- финализатор имеет высокую цену: объект с ним не собирается в первый проход, а помещается в отдельную очередь и переживает лишний цикл сборки. Плюс порядок финализации не определён, и обращаться к другим управляемым объектам изнутри нельзя, они могут быть уже собраны.
Зачем тогда финализатор нужен: как страховка для неуправляемых ресурсов. Если пользователь вашего класса забыл освободить ресурс явно, финализатор хотя бы освободит его когда-нибудь, а не оставит утечку навсегда.
Классическая схема связывает оба: общий метод освобождения с признаком, откуда он вызван, и явное снятие объекта с очереди финализации при обычном освобождении. Тогда штраф платится только при забытом вызове.
Современная практика, которую стоит назвать: финализаторы почти не пишут. Для неуправляемых дескрипторов есть специальный базовый класс, который уже реализует всё правильно и безопасно относительно прерывания потока. Обычный класс, владеющий только управляемыми ресурсами, реализует лишь метод освобождения, без финализатора.
Полезное дополнение: для ресурсов, освобождение которых требует ожидания, есть асинхронный вариант интерфейса и соответствующая конструкция.
Где спотыкаются
Пишут финализатор в классе без неуправляемых ресурсов.
Не снимают объект с очереди финализации при явном освобождении.
Обращаются к другим управляемым объектам внутри финализатора.
Полагаются на сборщик мусора для освобождения соединений.