Разница между деструктором и финализатором?

обратите внимание: этот вопрос касается разницы в терминологии между словами "деструктор" и "финализатор" и их правильного использования. Я просто привел примеры их использования в C# и C++/CLI, чтобы продемонстрировать, почему я задаю вопрос. Я хорошо знаю, как это реализовано в C# и CLR, но я спрашиваю о правильном использовании терминологии.


в мире c# термины "деструктор " и" финализатор", похоже, используются довольно много взаимозаменяемо, что я подозреваю, потому что спецификация C# описывает недетерминированную функциональность очистки, используя слово "деструктор", тогда как документация CLR всегда использует слово "финализатор", поэтому в пределах областей C# они означают одно и то же.

однако в спецификации C++/CLI существует различие между ними. Он позволяет как детерминированную, так и недетерминированную очистку и использует термин "деструктор" для детерминированной функциональности и "финализатор" для недетерминированной функциональности:

финализатор обеспечивает недетерминированную очистку. Финализатор-это функция "последнего шанса", которая выполняется во время сборки мусора, обычно на объекте, деструктор которого не был выполнен.

дополнительно описание Википедии деструктор и финализатор укажите, что деструкторы и завершители являются отдельными понятиями и поддерживают C++/CLI использование spec терминов в отношении детерминизма:

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

вопросы:

  • существует ли, с точки зрения информатики, четко определенная разница между" деструктором " и " финализатором", или терминология-это то, что можно определить только контекстуально?

  • Если есть четко определенная разница, то почему спецификация C# использует "неправильную" терминологию?

4 ответов


1) существует ли четко определенная разница между "деструктором" и "финализатором", используемыми в промышленности или академических кругах?

там, конечно, кажется, есть. Разница, по-видимому, в том, что деструкторы-это методы очистки, которые вызываются детерминированно, тогда как завершители запускаются, когда сборщик мусора говорит им об этом.

2) в этом случае спецификация C# ошибается-финализаторы называются "деструкторами" в C#. Почему авторы спецификации C# получили ее не так?

Я не знаю, но догадываюсь. На самом деле, у меня есть две догадки.

догадка №1 заключается в том, что 12 мая 1999 года в Википедии не было статьи, четко описывающей тонкую разницу между этими двумя понятиями. Это потому, что не было Википедии. Помню, когда не было Википедии? Темные века, чувак. Ошибка может быть честной ошибкой, полагая, что эти два термина идентичны.

черт, насколько я знаю, два термина были идентично 12 мая 1999 года, и разница в определениях только эволюционировала позже, так как стало очевидно, что существует необходимость устранить неоднозначность между нетерпеливыми и ленивыми методами очистки.

догадка №2 заключается в том, что 12 мая 1999 года Комитет по языковому дизайну пожелал оставить открытой возможность того, что "деструктор" может быть реализован как нечто другое чем финализатора. То есть "деструктор" был разработан как концепция языка C#, которая не обязательно один .Концепция сети "финализатор". При разработке языка в то же время, как структура, на которой он находится, также разрабатывается, иногда вы хотите изолировать себя от поздних изменений дизайна в своих подсистемах.

Примечания языкового комитета за 12 мая 1999 года, в частности, гласят:

мы будем использовать термин "деструктор" для элемента, который выполняет когда экземпляр восстанавливается. Занятия можете иметь деструкторы; структуры не могут. В отличие от C++, деструктор не может быть вызывается явно. Разрушение недетерминированный – вы не можете надежно знать, когда деструктор будет выполняться, за исключением того, что он выполняется в некоторых после все ссылки на объект был освобожден. Этот деструкторы в цепочке наследования называются в порядке, потомок к наименьшему потоку. Там нет необходимости (и нет возможности) для производный класс для явного вызова основа деструктор. Компилятор C# компилирует деструкторы в соответствующее представление среды. Для эта версия, которая, вероятно, означает экземпляр finalizer, который отличается в метаданных. CLR может обеспечить статические финализаторы в будущее; мы не видим никакого барьера C# с использованием статических финализаторы.

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


строго говоря, у C# нет деструктора (я считаю, что спецификация C# сбивает с толку в этом пункте). Финализатор C#выглядит как деструктор C++, но, как вы говорите, недетерминирован. C# имеет детерминированную очистку в виде IDisposable::Dispose (но это все еще не называется деструктором).

C++ / CLI имеет детерминированные деструкторы, которые выглядят как деструкторы c++. На уровне CLI эти карты на IDisposable::Dispose() (IDisposable реализован для вас ). C++/CLI имеет недетерминированные финализаторы, которые выглядят как деструкторы, но используют ! префикс вместо префикса^.

тот факт, что C++/CLI использует тот же синтаксис для деструкторов, что C# использует для финализаторов, может быть немного запутанным, но он лучше подходит для C++, который имеет сильную традицию детерминированного разрушения.

к сожалению, отсутствие универсальных определений этих терминов означает, что вам всегда нужно уточнить, о чем вы говорите. Лично я всегда использую слово финализатор когда речь идет о концепции C# и резерве деструктор для контекстов, где это определенно подразумевает детерминированное разрушение.

[обновление] С момента моего первоначального сообщения здесь Эрик Липперт опубликовал свой ответ (принятый ответ) и продолжил блоге на то же самое. Я рад видеть, что мы согласны: -)


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

EDIT: чтобы быть более подробным; спецификация языка C# определяет "деструктор" как метод экземпляра C# в классе. "деструктор", таким образом, является частью грамматики C# - деструкторы-это лингвистический объект, появляющийся в исходном коде.

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

"финализатор" - это термин, используемый в Общеязыковой среде выполнения, например, в вызовах GC.WaitForPendingFinalizers(), и это относится к любому языку .net, а не только к c#. Любой ссылочный тип .net может иметь финализатор. Для класса C# (артефакт исходного кода) деструктор компилируется в метод CIL, который является финализатором типа CLR.

или просто деструктор это финализатор as исходный код это код ;)


Если мы будем придерживаться "детерминированного" определения деструкторов, то я бы сказал, что в объектах .NET нет деструкторов, если явно не реализовано с помощью интерфейс IDisposable.