Общая система типов в .NET (Common Type System, CTS)

Как мы уже знаем, платформа .NET и язык программирования C# — это не тождественные понятия. В .NET используется общая система типов (Common Type System, CTS). Что это за система типов и зачем она потребовалась в .NET мы и рассмотрим в этой части. Здесь мы рассмотрим состав CTS, а также классифицируем некоторые типы данных, используемые в C# по нескольким признакам.

CTS и цели её разработки

Современное программное обеспечение может разрабатываться сразу на нескольких языках программирования. Например, графический интерфейс приложения может разрабатываться на одном языке, часть программы, отвечающая за сложные вычисления — на другом, а плагины к приложению — вообще на третьем языке программирования. При этом, каждый язык программирования может использовать (и использует) свою систему типов и правила хранения значений переменных в памяти. В результате, раньше, когда мы разрабатывали приложения без .NET, то могли сталкиваться с различными проблемами. Например, языки Delphi и C++ по-разному хранят в памяти строки и при попытке использовать библиотеку (DLL), разработанную на С++ в приложении Delphi мы сталкивались с тем, что нам необходимо было каким-либо образом «научить» программу на Delphi читать и передавать строки в библиотеку на C#. В том числе, чтобы избежать таких проблем и была разработана общая система типов .NET.

Платформа .NET может использоваться для разработки приложений на различных языках программирования, не только на C#. Например, для взаимодействия с .NET мы можем использовать VB.NET, F#, C++ и другие языки. Common Type System позволяет использовать единые правила по использованию тех или иных типов данных. Таким образом, какой бы язык программирования мы бы не использовали для .NET, переменная будет храниться и интерпретироваться приложением абсолютно одинаково.

Сами разработчики .NET указывают следующие основные задачи CTS:

  • формирование инфраструктуры, которая позволяет обеспечивать межъязыковую интеграцию, безопасность типов и высокопроизводительное выполнение кода.
  • предоставление объектно-ориентированной модели, поддерживающую полную реализацию многих языков программирования.
  • определение правил, которых необходимо придерживаться в языке. Эти правила помогают обеспечить взаимодействие объектов, написанных на разных языках.
  • предоставление библиотеки, содержащей типы-примитивы (например, BooleanByteCharInt32 и UInt64 и  так далее), используемые в разработке приложений.

Система общих типов CTS на платформе .NET поддерживает следующие пять категорий типов:

  • Классы
  • Структуры
  • Перечисления
  • Интерфейсы
  • Делегаты

В каждой категории типов может содержаться свой набор типов данных. Вначале рассмотрим как в .NET/C#, в принципе, классифицируются типы данных.

Ссылочные типы, типы значений, встроенные типы, псевдонимы типов и т.д.

При разработке приложений на C# мы будем часто встречать различные названия типов данных, используемых в приложении, например, «встроенный тип» или «примитивный тип», поэтому стоит потратить немного времени и разобраться с этими терминами немного по-подробнее.

Ссылочные типы и типы значений

Все типы данных в .NET/C# подразделяются на две большие группы — это типы значений и ссылочные типы. Со многими из этих типов данных мы обязательно познакомимся более подробно в других частях учебника, а пока просто классифицируем их по принятым в .NET/C# признакам.

Если переменной присвоить тип, относящийся к типам значений, то она будет хранить непосредственно значение. В соответствии со спецификацией языка C#, к типам значений относятся:

Если же для переменной используется ссылочный тип, то такая переменная будет хранить не само значение, а ссылку на значение этой переменной в памяти. Опять же, сильно не вдаваясь в подробности, можно привести такую аналогию: переменная ссылочного типа — это «визитка», то есть, обращаясь к значению этой переменной мы можем узнать где находится конкретное значение. К ссылочным типам в .NET/C# относятся следующие типы данных:

Встроенные типы данных в C#

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

Группа Псевдоним типа в C# Тип .NET Описание
Тип значений bool System.Boolean используется для представления логических значений, которые могут иметь значение true (истина) или false(ложь)
byte System.Byte целое число в диапазоне от 0 до 255
sbyte System.SByte целое число в диапазоне от -128 до 127
char System.Char символ в кодировке UTF-16
decimal System.Decimal вещественное число в диапазоне от ±1,0 x 10-28 до ±7,9228 x 1028
double System.Double вещественное число в диапазоне от ±5,0 × 10−324 до ±1,7 × 10308
float System.Single вещественное число в диапазоне от ±1,5 x 10−45 до ±3,4 x 1038
int System.Int32 целое число в диапазоне от -2 147 483 648 до 2 147 483 647
uint System.UInt32 целое число в диапазоне от 0 до 4 294 967 295
nint System.IntPtr целое число диапазон значений которого зависит от платформы (определяемой во время выполнения)
nuint System.UIntPtr целое число диапазон значений которого зависит от платформы (определяемой во время выполнения)
long System.Int64 целое число в диапазоне от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807
ulong System.UInt64 целое число в диапазоне от 0 до 18 446 744 073 709 551 615
short System.Int16 целое число в диапазоне от -32 768 до 32 767
ushort System.UInt16 целое число в диапазоне от 0 до 65 535
Ссылочный тип object System.Object базовый тип для всех типов CTS
string System.String строка, состоящая из символов в кодировке UTF-16
dynamic System.Object динамический тип

Также, согласно документации, Microsoft, к встроенным типам относится ссылочный тип delegate (делегат)

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

System.Int32 i;

или так:

using System;
Int32 i;

Во втором случае мы вначале подключаем к нашему проекту пространство имен System, а затем используем тип переменной уже без названия пространства имен вначале типа. Чтобы сократить исходный код, мы можем использовать псевдоним (этот способ наиболее часто используется при объявлении переменных встроенных типов данных):

int i;

Простые типы

К простым типам данных относятся все типы значений из базовых типов. То есть, если посмотреть на таблицу, представленную выше, то становится понятным, что к простым типам относятся целые числа, вещественные числа, а также типы bool и char.

Примитивные типы

Согласно документации на сайте Microsoft, к примитивным типам отнесены следующие типы данных: BooleanByteSByteInt16UInt16Int32UInt32Int64, UInt64, IntPtr, UIntPtr, Char, Double, Single. Как можно видеть, помимо рассмотренных ранее типов данных, к примитивным типам также относятся  типы IntPtr, UIntPtr и  Single. Первые два типа определяют указатель (не путать со ссылкой) на адрес в памяти. Для этих типов данных в C# используются псевдонимы nint и unint (см. таблицу выше) В этом учебнике мы не будем использовать указатели, так как это отдельный довольно интересный, но сложный для новичков вопрос. Последний тип — Single представляет собой вещественной число одинарной точности. Для Single в C# отсутствует псевдоним, а сам этот тип используется намного реже, чем, например, double или float.

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

Структуры

Такие типы данных используются для определения каких-либо сложных сущностей, позволяя объединять свойства этих сущностей в виде отдельно целостной структуры данных. Про структуры мы отдельно поговорим, пока же стоит обратить ваше внимание на следующий момент — .NET все типы-примитивы определяются как структуры. Чтобы убедиться в этом, достаточно определить в приложении какую-либо переменную с типом-примитивом и в следующей инструкции набрать после имени переменной символ точки. В Visual Studio вы увидите все свойства и методы этой структуры:


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

Console.WriteLine(Single.MinValue);
Console.WriteLine(Single.MaxValue);

А после запуска приложения вы увидите в консоли следующие значения:

-3,4028235E+38
3,4028235E+38

Перечисления

Перечисление (псевдоним в C# — enum) — это тип значения, который напрямую наследуется от типа System.Enum и предоставляет альтернативные имена для значений базового типа-примитива. Тип перечисления имеет имя, базовый тип, который должен быть одним из встроенных целочисленных знаковых или беззнаковых типов. Например, забегая немного вперед, рассмотрим такое перечисление:

enum Colors : byte 
{
    Red = 1,
    Green = 2,
    Blue = 3,
}

Базовый тип-примитив — byte. Этот тип также относится и к группе встроенных типов данных, альтернативные значения для чисел 1, 2 и 3 — Red, Green, Blue, соответственно.

Такие типы данных, как интерфейсы и делегаты мы будем рассматривать в отдельных главах учебника, поэтому их определения мы пока не будем приводить здесь (тем более, что нам пока вполне хватит для дальнейшей работы знаний о базовых типах). Однако, эти типы данных мы обязательно рассмотрим подробно, когда мы будем обладать необходимыми знаниями в C# для их использования.

Итого

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

Категория CTS Тип .NET Псевдоним в C# Описание Тип значений Встроенный тип Примитивный тип Простой тип
Структуры System.Boolean bool используется для представления логических значений, которые могут иметь значение true (истина) или false(ложь) Да Да Да Да
System.Byte byte целое число в диапазоне от 0 до 255 Да Да Да Да
System.SByte sbyte целое число в диапазоне от -128 до 127 Да Да Да Да
System.Char char символ в кодировке UTF-16 Да Да Да Да
Да Да Да Да
System.Double double вещественное число в диапазоне от ±5,0 × 10−324 до ±1,7 × 10308 Да Да Да Да
System.Single float вещественное число в диапазоне от ±1,5 x 10−45 до ±3,4 x 1038 Да Да Да Да
System.Int32 int целое число в диапазоне от -2 147 483 648 до 2 147 483 647 Да Да Да Да
System.UInt32 uint целое число в диапазоне от 0 до 4 294 967 295 Да Да Да Да
System.IntPtr nint целое число диапазон значений которого зависит от платформы (определяемой во время выполнения) Да Да Да Да
System.UIntPtr nuint целое число диапазон значений которого зависит от платформы (определяемой во время выполнения) Да Да Да Да
System.Int64 long целое число в диапазоне от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 Да Да Да Да
System.UInt64 ulong целое число в диапазоне от 0 до 18 446 744 073 709 551 615 Да Да Да Да
System.Int16 short целое число в диапазоне от -32 768 до 32 767 Да Да Да Да
System.UInt16 ushort целое число в диапазоне от 0 до 65 535 Да Да Да Да
System.Decimal decimal вещественное число в диапазоне от ±1,0 x 10-28 до ±7,9228 x 1028 Да Да Нет Да
System.Single вещественное число в диапазоне от -3,4028235E+38
3,4028235E+38
Да Нет Да Нет
Классы System.Object object базовый тип для всех типов CTS Нет Да Нет Нет
System.String string строка, состоящая из символов в кодировке UTF-16 Нет Да Нет Нет
System.Object dynamic динамический тип Нет Да Нет Нет
Перечисление System.Enum enum представляет собой перечисление Да Нет Нет Нет
Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии