Чтение онлайн

на главную - закладки

Жанры

Полное руководство. С# 4.0
Шрифт:

В языке C# имеется возможность определить метод, который будет вызываться не посредственно перед окончательным уничтожением объекта системой "сборки му сора". Такой метод называется деструктором и может использоваться в ряде особых случаев, чтобы гарантировать четкое окончание срока действия объекта. Например, деструктор может быть использован для гарантированного освобождения системного ресурса, задействованного освобождаемым объектом. Следует, однако, сразу же под черкнуть, что деструкторы — весьма специфические средства, применяемые только в редких, особых случаях. И, как правило, они не нужны. Но здесь они рассматривают ся вкратце ради полноты представления о возможностях языка С#.

Ниже приведена общая форма деструктора: ~имя_класса { // код деструктора }

где имя_класса означает имя конкретного класса. Следовательно, деструктор объяв ляется

аналогично конструктору, за исключением того, что перед его именем указы вается знак "тильда" (~). Обратите внимание на то, что у деструктора отсутствуют воз вращаемый тип и передаваемые ему аргументы.

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

Следует, однако, иметь в виду, что деструктор вызывается непосредственно перед "сборкой мусора". Он не вызывается, например, в тот момент, когда переменная, со держащая ссылку на объект, оказывается за пределами области действия этого объек та. (В этом отношении деструкторы в C# отличаются от деструкторов в C++, где они вызываются в тот момент, когда объект оказывается за пределами области своего дей ствия.) Это означает, что заранее нельзя знать, когда именно следует вызывать деструк тор. Кроме того, программа может завершиться до того, как произойдет "сборка му сора", а следовательно, деструктор может быть вообще не вызван. Ниже приведен пример программы, демонстрирующий применение деструкто ра. В этой программе создается и уничтожается большое число объектов. В какой-то момент по ходу данного процесса активизируется "сборка мусора" и вызываются де структоры для уничтожения ненужных объектов. // Продемонстрировать применение деструктора. using System; class Destruct { public int x; public Destruct(int i) { х = i; } // Вызывается при утилизации объекта. ~Destruct { Console.WriteLine("Уничтожить " + х); } // Создает объект и тут же уничтожает его. public void Generator(int i) { Destruct о = new Destruct(i); } } class DestructDemo { static void Main { int count; Destruct ob = new Destruct(0); /* А теперь создать большое число объектов. В какой-то момент произойдет "сборка мусора". Примечание: для того чтобы активизировать "сборку мусора", возможно, придется увеличить число создаваемых объектов. */ for(count=1; count < 100000; count++) ob.Generator(count); Console.WriteLine( "Готово!"); } }

Эта программа работает следующим образом. Конструктор инициализирует пере менную х известным значением. В данном примере переменная х служит в качестве идентификатора объекта. А деструктор выводит значение переменной х, когда объект утилизируется. Особый интерес вызывает метод Generator, который создает и тут же уничтожает объект типа Destruct. Сначала в классе DestructDemo создается ис ходный объект ob типа Destruct, а затем осуществляется поочередное создание и уни чтожение 100 тыс. объектов. В разные моменты этого процесса происходит "сборка му сора". Насколько часто она происходит — зависит от нескольких факторов, в том числе от первоначального объема свободной памяти, типа используемой операционной си стемы и т.д. Тем не менее в какой-то момент начинают появляться сообщения, форми руемые деструктором. Если же они не появятся до окончания программы, т.е. до того момента, когда будет выдано сообщение "Готово!", попробуйте увеличить число созда ваемых объектов, повысив предельное количество подсчитываемых шагов в цикле for.

И еще одно важное замечание: метод WriteLine вызывается в деструкторе ~Destruct исключительно ради наглядности данного примера его использования. Как правило, деструктор должен воздействовать только на переменные экземпляра, определенные в его классе.

В силу того что порядок вызова деструкторов не определен точно, их не следует применять для выполнения действий, которые должны происходить в определенный момент выполнения программы. В то же время имеется возможность запрашивать "сборку мусора", как будет показано в части II этой книги при рассмотрении библио теки классов С#. Тем не менее инициализация "сборки мусора" вручную в большин стве случаев не рекомендуется, поскольку это может привести к снижению эффектив ности программы. Кроме того, у системы "сборки мусора" имеются свои особенно сти — даже если запросить "сборку мусора" явным образом, все равно нельзя заранее знать, когда именно будет утилизирован конкретный объект. Ключевое

слово this

Прежде чем завершать эту главу, необходимо представить ключевое слово this. Когда метод вызывается, ему автоматически передается ссылка на вызывающий объект, т.е. тот объект, для которого вызывается данный метод. Эта ссылка обозна чается ключевым словом this. Следовательно, ключевое слово this обозначает именно тот объект, по ссылке на который действует вызываемый метод. Для того чтобы стало яснее назначение ключевого слова this, рассмотрим сначала пример программы, в которой создается класс Rect, инкапсулирующий ширину и высо ту прямоугольника и включающий в себя метод Area, возвращающий площадь прямоугольника. using System; class Rect { public int Width; public int Height; public Rect(int w, int h) { Width = w; Height = h; } public int Area { return Width * Height; } } class UseRect { static void Main ( Rect r1 = new Rect(4, 5); Rect r2 = new Rect(7, 9); Console.WriteLine("Площадь прямоугольника r1: " + r1.Area); Console.WriteLine("Площадь прямоугольника r2: " + r2.Area); } }

Как вам должно уже быть известно, другие члены класса могут быть доступны не посредственно без дополнительного уточнения имени объекта или класса. Поэтому оператор return Width * Height;

в методе Area означает, что копии переменных Width и Height, связанные с вы зывающим объектом, будут перемножены, а метод возвратит их произведение. Но тот же самый оператор можно написать следующим образом. return this.Width * this.Height;

В этом операторе ключевое слово this обозначает объект, для которого вызван метод Area. Следовательно, в выражении this.Width делается ссылка на копию переменной Width данного объекта, а в выражении this.Height — ссылка на копию переменной Height этого же объекта. Так, если бы метод Area был вызван для объ екта х, то ключевое слово this в приведенном выше операторе обозначало бы ссылку на объект х. Написание оператора без ключевого слова this представляет собой не более чем сокращенную форму записи.

Ключевое слово this можно также использовать в конструкторе. В этом случае оно обозначает объект, который конструируется. Например, следующие операторы в ме тоде Rect Width = w; Height = h;

можно было бы написать таким образом. this.Width = w; this.Height = h;

Разумеется, такой способ записи не дает в данном случае никаких преимуществ. Ради примера ниже приведен весь класс Rect, написанный с использованием ссыл ки this. using System; class Rect { public int Width; public int Height; public Rect(int w, int h) { this.Width = w; this.Height = h; } public int Area { return this.Width * this.Height; } } class UseRect { static void Main { Rect r1 = new Rect(4, 5); Rect r2 = new Rect(7, 9); Console.WriteLine("Площадь прямоугольника r1: " + r1.Area); Console.WriteLine("Площадь прямоугольника r2: " + r2.Area); } }

В действительности ключевое слово this не используется приведенным выше способом в программировании на С#, поскольку это практически ничего не дает, да и стандартная форма записи намного проще и понятнее. Тем не менее ключевому сло ву this можно найти не одно полезное применение. Например, в синтаксисе C# допу скается называть параметр или локальную переменную тем же именем, что и у пере менной экземпляра. В этом случае имя локальной переменной скрывает переменную экземпляра. Для доступа к скрытой переменной экземпляра и служит ключевое слово this. Например, приведенный ниже код является правильным с точки зрения синтак сиса C# способом написания конструктора Rect. public Rect(int Width, int Height) { this.Width = Width; this.Height = Height; }

В этом варианте написания конструктора Rect имена параметров совпадают с именами переменных экземпляра, а следовательно, скрывают их. Но для "обнаруже ния" скрытых переменных служит ключевое слово this.

ГЛАВА 7. Массивы и строки

В этой главе речь вновь пойдет о типах данных в С#. В ней рассматриваются массивы и тип string, а так же оператор цикла foreach. Массивы

Массив представляет собой совокупность перемен ных одного типа с общим для обращения к ним именем. В C# массивы могут быть как одномерными, так и многомер ными, хотя чаще всего применяются одномерные массивы. Массивы служат самым разным целям, поскольку они пре доставляют удобные средства для объединения связанных вместе переменных. Например, в массиве можно хранить максимальные суточные температуры, зарегистрированные в течение месяца, перечень биржевых курсов или же назва ния книг по программированию из домашней библиотеки.

Поделиться:
Популярные книги

Законы Рода. Том 10

Андрей Мельник
10. Граф Берестьев
Фантастика:
юмористическая фантастика
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 10

Офицер

Земляной Андрей Борисович
1. Офицер
Фантастика:
боевая фантастика
7.21
рейтинг книги
Офицер

На границе империй. Том 3

INDIGO
3. Фортуна дама переменчивая
Фантастика:
космическая фантастика
5.63
рейтинг книги
На границе империй. Том 3

Наследие Маозари 6

Панежин Евгений
6. Наследие Маозари
Фантастика:
попаданцы
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Наследие Маозари 6

Камень. Книга вторая

Минин Станислав
2. Камень
Фантастика:
фэнтези
8.52
рейтинг книги
Камень. Книга вторая

Черный Маг Императора 11

Герда Александр
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Черный Маг Императора 11

Отмороженный 9.0

Гарцевич Евгений Александрович
9. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 9.0

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Гоплит Системы

Poul ezh
5. Пехотинец Системы
Фантастика:
фэнтези
рпг
фантастика: прочее
5.00
рейтинг книги
Гоплит Системы

Хозяйка покинутой усадьбы

Нова Юлия
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка покинутой усадьбы

Моя (не) на одну ночь. Бесконтрактная любовь

Тоцка Тала
4. Шикарные Аверины
Любовные романы:
современные любовные романы
7.70
рейтинг книги
Моя (не) на одну ночь. Бесконтрактная любовь

Газлайтер. Том 4

Володин Григорий
4. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 4

Боярышня Евдокия

Меллер Юлия Викторовна
3. Боярышня
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Боярышня Евдокия

Опасная любовь командора

Муратова Ульяна
1. Проклятые луной
Фантастика:
фэнтези
5.00
рейтинг книги
Опасная любовь командора