netlib.narod.ru< Назад | Оглавление | Далее >

Классы и структуры

Эти четыре типа данных — на самом деле их семь, так как три из них реализованы и в целочисленной форме, и в форме с плавающей точкой, — определены в пространстве имен System.Drawing. Интересно, что эти семь типов данных не peaлизованы как классы. Они являются структурами, а не классами, и это семь из восьми структур определенных в System.Drawing.

Структурный тип данных (определяемый ключевым словом struct) пришел в С# из С и C++. (В Java нет структурного типа данных.) В C++ классы и структуры очень схожи. В структурах C++ все методы и поля по умолчанию открыты, а в классах C++ — по умолчанию закрыты. Конечно, можно использовать ключевые слова public, private или protected для изменения видимости любого метода или поля в структурах и классах C++.

Классы и структуры в С# также очень схожи, но у них другие отличия, чем в C++. В С# все методы и поля (а также свойства и события) по умолчанию закрыты и в классах, и в структурах. Однако классы — это ссылочные типы (reference type), а структуры — это размерные типы (value type). В чем же различие? Давайте рассмотрим выражение:

  new Form()

Этот оператор выделяет блок памяти в области универсальной памяти, известной как куча (heap). Этот блок памяти должен быть достаточно большим, чтобы вместить экземпляр объекта Form, значит, он должен быть достаточно большим, чтобы вместить все поля экземпляра Form (т.е. нестатические поля). Если вы посмотрите документацию по .NET, то занимаемое объектом пространство покажется небольшим, но имейте в виду, что вы не видите закрытые (private) поля, а этих полей, несомненно, много.

Значение, возвращаемое оператором new, по существу является ссылкой на блок памяти, расположенный в куче. Эта ссылка на память и сохраняется в переменной form инструкцией вида:

  Form form = new Form();

To есть ссылочный тип означает: объект является указателем (ссылкой) на блок памяти.

Допустим, имеются такие инструкции:

  Form form2 = form;
  form2.Text = "Form 2 Text";

Вставим их в программу PaintEvent из главы 2, прямо перед вызовом Application.Run. Что произошло? У отображаемой нами формы, на которую ссылается form, появился заголовок «Form 2 Text». Почему это случилось? Потому что form является ссылкой. Инструкция

  Form form2 = form;

просто копирует этот указатель в form2. Она не создает новый экземпляр класса Form. Переменные form и form2 идентичны, т.е. ссылаются на один и тот же блок памяти и поэтому обращаются к одному и тому же объекту.

Понятно, что в повсеместном присваивании указателей нет нужды. Рассмотрим такую последовательность инструкций:

  int а = 5;
  int b = a;
  a = 10;

Вы не хотели бы, чтобы это означало, что а и b являются одинаковыми указателями, которые всегда ссылаются на одно и то же число, и что b равно 10! Это было бы абсурдом. Поэтому числа в С# являются размерными типами. Переменная любого числового размерного типа не является указателем на область памяти, в которой хранится число, а содержит само число.

В документации пространства имен System вы обнаружите, что большинство базовых типов — Boolean, Byte, Char, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, UInt64 — определены как структуры, а не как классы. Структуры унаследованы от ValueType, который в свою очередь унаследован от Object. Вы можете думать о размерных типах, как о «легковесных объектах», и действительно, использовать struct надо только для типов, которые имеют небольшие размеры и могут часто создаваться и уничтожаться.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz