Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
12
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

10.13Деструкторы

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

объявление_деструктора: атрибутынеобязательно Externнеобязательно ~ идентификатор ( ) тело_деструктора

тело_деструктора: блок ;

Объявление_деструктора может включать набор атрибутов (§17).

Идентификатор в деклараторе_деструктора должен указывать имя класса, в котором объявлен деструктор. Если указано любое другое имя, происходит ошибка времени компиляции.

Если в объявление деструктора включен модификатор extern, деструктор называется внешним деструктором. Поскольку объявление внешнего деструктора не предоставляет фактическую реализацию, его тело_деструктора состоит из точки с запятой. Во всех других деструкторах тело_деструктора состоит из блока, в котором указаны операторы для уничтожения экземпляра класса. Тело_деструктора в точности соответствует телу_метода метода экземпляра с типом возвращаемого значения void (§10.6.10).

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

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

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

Выполнение примера

using System;

class A { ~A() { Console.WriteLine("A's destructor"); } }

class B: A { ~B() { Console.WriteLine("B's destructor"); } }

class Test { static void Main() { B b = new B(); b = null; GC.Collect(); GC.WaitForPendingFinalizers(); } }

даст на выходе:

B’s destructor A’s destructor

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

Деструкторы реализуются переопределением виртуального метода Finalize для System.Object. Программам C# запрещено переопределять этот метод или вызывать его (или его переопределения) непосредственно. Например, программа

class A { override protected void Finalize() {} // error

public void F() { this.Finalize(); // error } }

содержит две ошибки.

Поведение компилятора такое, как будто этот метод и его переопределения вовсе не существуют. Таким образом, эта программа:

class A { void Finalize() {} // permitted }

допустима, а показанный метод скрывает метод Finalize объекта System.Object.

Обсуждение поведения, когда исключение вызывается из деструктора, см. в §16.3.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]