Pull to refresh

Есть ли деструктор в C#?

Reading time 3 min
Views 45K
Итак, начнем с того, что существует два типа ресурсов — управляемые и неуправляемые. Насчет первых можно совсем не беспокоиться — ими займется сборщик мусора. А вот с неуправляемыми ресурсами дела обстоят куда сложнее. Наш мусорщик не знает, как их освободить, поэтому нам самим приходится заниматься этим вопросом.

Чем отличается деструктор от финализатора

Деструктор — это метод для деинициализации объекта. Здесь важно упомянуть о такой штуке, как deterministic destruction. То есть мы точно знаем, когда объект будет удален. Чаще всего это происходит, когда заканчивается область видимости объекта, или программист явно освобождает память(в с/с++).

А вот определение финализатора из Википедии.

Финализатор — это метод класса, который автоматически вызывается средой исполнения в промежутке времени между моментом, когда объект этого класса опознаётся сборщиком мусора как неиспользуемый, и моментом удаления объекта (освобождения занимаемой им памяти). Это уже обратная штука — nondeterministic destruction.
То есть главный минус финализатора в том, что мы не знаем, когда он вызовется. Это может создать огромное количество проблем.

Но деструктор и финализатор в .NET это не то же самое, что просто деструктор и финализатор в обычном мире.

В Visual C# есть финализатор, который создается с помощью синтаксиса создания деструктора в С++, и который некоторыми даже называется как деструктор, хотя таковым не является. Выполнен он через метод Finalize, который нельзя переопределить(в C# нет, но в VB можно), поэтому и приходится использовать синтаксис деструктора через тильду(~ClassName). И только при компиляции в IL, компилятор называет его Finalize. При выполнении этот метод также вызывает финализатор родительского класса.

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

Если заглянуть в спецификацию языка программирования C#(4.0 на данный момент), то там слово «finalizer» ни разу не встречается. Ну это еще можно объяснить. Финализатор тесно связан со сборщиком мусора, который в свою очередь является частью среды выполнения(CLR в нашем случае), но не самого языка программирования.

Теперь пойдем еще дальше и залезем в спецификацию CLI(ECMA-335). Здесь вот что написано.

A class definition that creates an object type can supply an instance method (called a finalizer) to be called
when an instance of the class is no longer reachable.


Это, несомненно, описание финализатора, хотя на мой взгляд, немного неточное.

Далее, идем на msdn. Ни в одной статье не встречается слово finalizer в чистом виде — зато почти всегда используется слово деструктор. Возникает закономерный вопрос — почему люди называют деструктором то, что им не является. Получается, что майкрософтовские разработчики сознательно поменяли значение этого слова. И вот почему.

Мы знаем, что в Visual C# nondeterministic destruction. Это значит, что даже если область видимости объекта закончилась, и сборщик мусора понял, что можно освобождать занимаемую им память, не факт, что это произойдет незамедлительно. То есть это чистой воды финализатор. Так как он использует синтаксис, который во всех языках используется для деструктора, можно предположить, что в Visual C# нет способа определить деструктор(в общем понимании). Это значит, что его просто-напросто нет. Да, необходимости в нем тоже особой нет, но нужно согласиться с тем, что и самого деструктора в Visual C# быть не может.

Вывод — либо я идиот, и совсем все неправильно понял(а вероятность этого довольно высока), либо нужно смириться с этим, и называть деструктором то, что внешне на него похоже(тильда, привет), но по сути является финализатором. Надо же как-то жить в этом мире.
Tags:
Hubs:
+9
Comments 77
Comments Comments 77

Articles