Подтвердить что ты не робот

Наследование и деструкторы в С#

Согласно этому, в нем указано, что Destructors cannot be inherited or overloaded. В моем случае для всех подклассов деструкторы будут идентичными. Это в значительной степени говорит мне, что я должен определить один и тот же деструктор в каждом подклассе. Я не могу объявить деструктор в базовом классе и уничтожить дескриптор? Скажем, у меня есть что-то вроде этого:

class A
{
    ~A()
    {
        SomethingA();
    }

}

class B : A
{

}

B b = new B();

Когда B уничтожается, его деструктор не будет вызван?

4b9b3361

Ответ 1

В соответствии с этим, он заявляет, что деструкторы не могут быть унаследованы или перегружены.

Правильно. Деструкторы не являются наследуемыми членами и не являются виртуальными и поэтому не могут быть переопределены. Они всегда имеют одну и ту же подпись, поэтому они не могут быть перегружены.

В моем случае для всех подклассов деструкторы будут одинаковыми.

Тот факт, что вы задаете такой основной вопрос, говорит мне, что вы не должны внедрять деструктор в первую очередь. Реализация деструктора правильно - это одна из самых сложных задач в С# во всех, кроме самых тривиальных случаях. Почему вы считаете, что вам нужно реализовать деструктор?

Значит ли это, что я должен определить один и тот же деструктор в каждом подклассе?

Нет, совсем нет. Как вы пришли к такому выводу из того факта, что деструкторы не наследуются?

Нет способа, чтобы я мог объявить деструктор в базовом классе и иметь дескриптор уничтожения?

Конечно, это разумная вещь, если вы намереваетесь реализовать деструктор в первую очередь.

Когда B уничтожен, его деструктор не будет вызван?

Это неверно.

Мне кажется, что вам потребовалось бы намного меньше времени, чтобы попробовать это самостоятельно, чем задавать здесь вопрос и ждать ответа.

Когда действительно вызываются деструкторы? Является ли он сборкой мусора, когда переменная выходит за рамки?

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

Когда объект определяется как недоступный из корня gc коллекционером, а у объекта есть финализатор, который не был подавлен, тогда объект продвигается к следующему поколению, помещая его в очередь завершения для обслуживания финализатор. Если нет, его память будет восстановлена.

Когда поток финализатора начинает работать, он запускает все деструкторы объекта. (Деструкторы будут выполняться в порядке от большинства полученных до наименее полученных.) После этого процесса объект может быть или не быть недоступным, а завершение может быть или не быть подавлено. Если объект определен как недостижимый, тогда весь процесс начинается снова.

Я не могу подчеркнуть, насколько хорошо вам нужно понять процесс GC, чтобы сделать это правильно. Когда вы пишете деструктор, он запускается в среде, где ничего не имеет смысла. Все ссылки в объекте могут быть объектами, которые коренится только в очереди финализатора; обычно все ссылки - это жить. Ссылки могут быть для объектов, которые уже завершены. Деструкторы запускаются в другом потоке. Деструкторы выполняются, даже если конструктор вышел из строя, поэтому объект может быть даже не сконструирован должным образом. Поля неатомных типов значений могут быть только частично записаны - вполне возможно, что двойное поле имеет только четыре из его байтов, заданных конструктором, когда поток прерывается; финализатор увидит это частично написанное поле. Деструкторы выполняются, даже если объект был помещен в несогласованное состояние с помощью прерванной транзакции. И так далее. Вы должны быть чрезвычайно защитными при написании деструктора.

Этот ответ также может помочь:

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

Ответ 2

Это не деструктор в С#. Он известен как финализатор; и когда он называется, является недетерминированным. Вы на самом деле не можете рассчитывать на то, что он вообще будет вызван.

Финализаторы используются в качестве крайней меры для очистки неуправляемых ресурсов. Вы должны изучить Dispose pattern.

Ответ 3

Финализатор, который вы определили в A, вызывается, когда уничтожается экземпляр B.

Если вы определяете финализатор как в A, так и в B, первый конкретный финализатор (B) будет работать первым, а затем наименее конкретный (A).

Ответ 4

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

Ответ 6

Ну, я не знаю о деструкторах, но у вас есть другие полезные методы для очистки, такие как Finalize() и Dispose() из IDisposable.