Финализаторы и деструкторы, что говорит Википедия? - PullRequest
2 голосов
/ 04 мая 2011

Как я понимаю, есть два лагеря по этому вопросу - первый думает, что финализатор - это деструктор, специфичный для C #. Поэтому они думают, что эти две вещи одинаковы.

Второй лагерь считает, что есть небольшая разница - написано в Википедии - «термин« деструктор »обычно используется для обозначения детерминистически вызванной очистки, тогда как« финализатор »запускается, когда сборщик мусора говорит запустить его».

Но позвольте мне кое-что прояснить для себя. Детерминированная очистка? В спецификации C # и msdn написано, что деструкторы не могут быть вызваны (они вызываются автоматически). Единственный случай, когда они могут быть вызваны автоматически - это сборщик мусора.

Так что я не вижу никакой разницы между детерминистически вызванной очисткой и случаем со сборщиком мусора.

Это так или нет?

Ответы [ 6 ]

5 голосов
/ 04 мая 2011

Существует огромная разница. Детерминированный вызов означает, что вы знаете, когда он будет вызван.

В C ++:

{
    Person a;
    a.Name = "John";
    InvitePerson(a);
} // <-- Destructor is always invoked when the scope is left

В C #:

{
    Person a = new Person();
    a.Name = "John";
    InvitePerson(a);
} // <-- The finalizer is NOT invoked when the scope is left

Как указывалось, основное отличие:
В C # и других языках сборки мусора вы не знаете , когда или даже , если , будет выполнен финализатор.
Однако в C ++ вы знаете , когда и , что деструктор выполняется, как только объект выходит из области видимости.

3 голосов
/ 04 мая 2011

Официальная позиция заключается в том, что в C # есть деструкторы (~ClassName() {}), и они отображаются на System.Object.Finalize(). В VB.NET вы просто переопределяете Finalize так же, как ToString.

Хотя есть некоторая путаница, вы правы в этом. Но это больше о Finalize / Destructor vs Dispose. Вот сообщение от Эрика Липперта (со ссылкой на Википедию):

Да, согласно этим определениям, спецификация C # получает это неправильно. Что мы называем «Деструктор» в спецификации на самом деле финализатор, и что мы называем Метод «Dispose ()», вызываемый «Использование» заявление на самом деле «Деструктор».

1 голос
/ 04 мая 2011

Второе мнение правильнее.Вы не можете гарантировать, что деструктор объекта будет запущен в указанное время.Так что это не дескриптор, как в C ++, где вы можете явно вызвать delete obj.В .Net для объектов, которым необходимо очистить некоторые ресурсы после использования, вы должны реализовать IDisposable и явно вызывать Dispose, когда закончите работу с объектом или с using() block

1 голос
/ 04 мая 2011

В C # финализатор и деструктор - это разные имена для одной и той же вещи.

Спецификация языка C # (1.6.7.6) фактически называет их деструкторами.Однако, поскольку деструктор имени может быть легко принят за аналог C ++ (который сильно отличается от деструктора в C #), имеет смысл вместо этого использовать термин финализатор.

0 голосов
/ 04 мая 2011

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

Однако нет «детерминированной очистки», если вы полагаетесь на сборщик мусора.Ваш вывод:

Так что я не вижу никакой разницы между детерминированной очисткой и случаем с сборщиком мусора.

... не имеет смыслав контексте вы даете это.Разница в том, что один вызывается детерминистически, а другой - нет.

0 голосов
/ 04 мая 2011

Детерминистически означает, что вы можете освободить память в любой момент времени.Это невозможно в C #, поскольку деструктор вызывается GC через поток финализатора в неопределенный момент времени.

...