Когда я должен создать деструктор?

Например:

public class Person
{
    public Person()
    {
    }

    ~Person()
    {
    }
}

Когда мне нужно вручную создать деструктор? Когда вам нужно создать деструктор?

Ответ 2

UPDATE: этот вопрос был тема моего блога в мае 2015 года. Спасибо за большой вопрос! См. Блог для длинного списка ложных сведений, которые люди обычно верят в завершение.

Когда мне нужно вручную создать деструктор?

Почти никогда.

Обычно создается только деструктор, когда ваш класс держится за какой-то дорогостоящий неуправляемый ресурс, который нужно очистить, когда объект уходит. Лучше использовать шаблон одноразового использования, чтобы обеспечить очистку ресурса. Деструктор - это по существу уверенность в том, что, если потребитель вашего объекта забывает его утилизировать, ресурс по-прежнему будет очищен в конечном итоге. (Может быть).

Если вы сделаете деструктор чрезвычайно осторожным и понимаете, как работает сборщик мусора. Деструкторы действительно странные:

  • Они не работают в вашей теме; они бегают по собственной теме. Не вызывайте взаимоблокировки!
  • Необработанное исключение, выведенное из деструктора, - плохая новость. Это на собственной нити; кто его поймает?
  • Деструктор может быть вызван на объект после запуска конструктора, но до завершения конструктора. Правильно написанный деструктор не будет полагаться на инварианты, установленные в конструкторе.
  • Деструктор может "воскресить" объект, снова создавая мертвый объект. Это действительно странно. Не делайте этого.
  • Деструктор может никогда не запускаться; вы не можете полагаться на объект, который когда-либо планировался для завершения. Вероятно, это будет, но это не гарантия.

Почти ничего, что обычно верно, истинно в деструкторе. Будьте действительно, очень осторожны. Написание правильного деструктора очень сложно.

Когда вам нужно создать деструктор?

При тестировании части компилятора, который обрабатывает деструкторы. Мне никогда не приходилось делать это в производственном коде. Я редко пишу объекты, которые управляют неуправляемыми ресурсами.

Ответ 3

Он называется "финализатор", и вы обычно должны создавать его только для класса, состояние которого (например: поля) включает неуправляемые ресурсы (то есть: указатели на дескрипторы, полученные через вызовы p/invoke). Однако в .NET 2.0 и более поздних версиях на самом деле есть лучший способ справиться с очисткой неуправляемых ресурсов: SafeHandle. Учитывая это, вам больше не нужно будет снова писать финализатор.

Ответ 4

Вам не нужен один, если ваш класс не поддерживает неуправляемые ресурсы, такие как дескрипторы файлов Windows.

Ответ 5

Он называется деструктором/финализатором и обычно создается при реализации удаленного шаблона.

Это резервное решение, когда пользователь вашего класса забывает вызывать Dispose, чтобы убедиться, что (в конце концов) ваши ресурсы освобождены, но у вас нет никакой гарантии, когда вызывается деструктор.

В этом вопросе о переполнении стека принятый ответ правильно показывает, как реализовать шаблон размещения. Это необходимо только в том случае, если ваш класс содержит любые неуправляемые ресурсы, которые сборщику мусора не удается очистить.

Хорошая практика заключается в том, чтобы не реализовывать финализатор, не предоставляя также пользователю класса возможность вручную удалять объект, чтобы сразу освободить ресурсы.

Ответ 6

Когда у вас есть неуправляемые ресурсы, и вам нужно убедиться, что они будут очищены, когда ваш объект уйдет. Хорошим примером могут быть COM-объекты или обработчики файлов.

Ответ 7

Я использовал деструктор (только для целей отладки), чтобы увидеть, был ли объект очищен из памяти в области приложения WPF. Я был не уверен, что сбор мусора действительно очищает объект от памяти, и это был хороший способ проверить.

Ответ 8

Деструкторы предоставляют неявный способ освобождения неуправляемых ресурсов, инкапсулированных в ваш класс, они вызываются, когда GC приближается к нему, и они неявно называют метод Finalize базового класса. Если вы используете много неуправляемых ресурсов, лучше предоставить явный способ освобождения этих ресурсов через интерфейс IDisposable. См. Руководство по программированию на С#: http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx