Для большинства процедурных языков, реально используемых программистами — Паскаль, C++, Java, Visual Basic, С#, - система встроенных типов более или менее одинакова. Всегда в языке присутствуют арифметический, логический (булев), символьный типы. Арифметический тип всегда разбивается на подтипы. Всегда допускается организация данных в виде массивов и записей (структур). Внутри арифметического типа всегда допускаются преобразовани
я, всегда есть функции, преобразующие строку в число и обратно. Так что, мой читатель, Ваше знание, по крайней мере, одного из процедурных языков позволяет построить общую картину системы типов и для языка С#. Отличия будут в нюансах, которые и придают аромат и неповторимость языку.Поскольку язык C# является непосредственным потомком языка C++, то и системы типов этих двух языков близки и совпадают вплоть до названия типов и областей их определения. Но отличия, в том числе принципиального характера, есть и здесь.
Давайте рассмотрим, как устроена система типов в языке С#, но вначале для сравнения приведу классификацию типов в стандарте языка C++.
Стандарт языка C++ включает следующий набор фундаментальных
типов.1. Логический тип (
2. Символьный тип (
3. Целые типы. Целые типы могут быть одного из трех размеров —
4. Типы с плавающей точкой. Эти типы также могут быть одного из трех размеров —
Кроме того, в языке есть
5. Тип
Язык позволяет конструировать типы.
6. Указатели (например,
7. Ссылки (например,
8. Массивы (например,
Язык позволяет конструировать пользовательские типы
9. Перечислимые типы (
10. Структуры (
11. Классы.
Первые три вида типов называются интегральными или счетными. Значения их перечислимы и упорядочены. Целые типы и типы с плавающей точкой относятся к арифметическому типу. Типы подразделяются также на встроенные и типы, определенные пользователем.
Эта схема типов сохранена и в языке С#. Однако здесь на верхнем уровне используется и другая классификация, носящая для C# принципиальный характер. Согласно этой классификации все типы можно разделить на четыре категории:
1. Типы-значения (
2. Ссылочные (
3. Указатели (
4. Тип
Эта классификация основана на том, где и как хранятся значения типов. Для ссылочного типа значение задает ссылку на область памяти в "куче", где расположен соответствующий объект. Для значимого типа используется прямая адресация, значение хранит собственно данные, и память для них отводится, как правило, в стеке.
В отдельную категорию выделены указатели, что подчеркивает их особую роль в языке. Указатели имеют ограниченную область действия и могут использоваться только в небезопасных блоках, помеченных как
Особый статус имеет и тип void, указывающий на отсутствие какого-либо значения.
В языке C# жестко определено, какие типы относятся к ссылочным, а какие — к значимым. К значимым типам относятся: логический, арифметический, структуры, перечисление. Массивы, строки
и классы относятся к ссылочным типам. На первый взгляд, такая классификация может вызывать некоторое недоумение, почему это структуры, которые в C++ близки к классам, относятся к значимым типам, а массивы и строки — к ссылочным. Однако ничего удивительного здесь нет. В C# массивы рассматриваются как динамические, их размер может определяться на этапе вычислений, а не в момент трансляции. Строки в C# также рассматриваются как динамические переменные, длина которых может изменяться. Поэтому строки и массивы относятся к ссылочным типам, требующим распределения памяти в "куче".Со структурами дело сложнее. Структуры C# представляют частный случай класса. Определив свой класс как структуру, программист получает возможность отнести класс к значимым типам, что иногда бывает крайне полезно. Замечу, что в хорошем объектном языке Eiffel программист может любой класс объявить развернутым (