Common Type System
Common Type System (сокр. CTS, рус. Общая система типов) — часть .NET Framework, формальная спецификация, определяющая, как какой-либо тип (класс, интерфейс, структура, встроенный тип данных) должен быть определён для его правильного выполнения средой .NET. Кроме того, данный стандарт определяет, как определения типов и специальные значения типов представлены в компьютерной памяти. Целью разработки CTS было обеспечение возможности программам, написанным на различных языках программирования, легко обмениваться информацией. Как это принято в языках программирования, тип может быть описан как определение набора допустимых значений (например, «все целые от 0 до 10») и допустимых операций над этими значениями (например, сложение и вычитание).
Спецификация для CTS закреплена в стандарте Ecma 335, озаглавленном «Common Language Infrastructure (CLI) Partitions I to VI» (рус. Общеязыковая инфраструктура, главы с I по IV). CLI и CTS были разработаны корпорацией Microsoft, а Microsoft .NET framework — реализация стандарта.
Функции Common Type System
- Формирует фреймворк, способствующий межъязыковой интеграции, безопасности типов, а также высокой производительности исполнения кода.
- Обеспечивает объектно-ориентированную модель, поддерживающую полную реализацию множества языков программирования.
- Определяет правила, которым должны следовать языки, что в том числе позволяет гарантировать, что объекты, написанные на разных языках могут друг с другом взаимодействовать.
- CTS определяет правила, гарантирующие, что типы данных объектов, написанные на разных языках, смогут взаимодействовать друг с другом.
- CTS определяет правила для видимости типов и доступа к членам типа, то есть CTS утверждает правила, по которым сборки формируют области видимости для типа, а Common Language Runtime дополняет правила видимости.
- CTS определяет правила, управляющие наследованием типов, виртуальными методами и продолжительностью существования объектов.
- Языки, поддерживаемые платформой .NET, могут реализовывать все или некоторые из общих типов данных.
При округлении дробных значений благодаря фреймворку по умолчанию применяется метод банковского округления. Начиная с версии 2, «симметричное арифметическое округление» («англ. Symmetric Arithmetic Rounding») (округляет до ближайшего числа со стороны нуля) также доступно программистам в качестве дополнительной возможности[1].
Категории типов
Стандартная система типов поддерживает две основные категории типов:
- Значимые типы
- Переменные значимых типов непосредственно содержат данные, а экземпляры значимых типов располагаются или в стеке или непосредственно в теле других объектов. Значимые типы могут быть встроенными (реализуются средой исполнения), пользовательскими или перечислениями. Значение значимого типа может быть преобразовано в значение ссылочного типа путём применения к нему процедуры упаковки (боксинга, boxing).
- Ссылочные типы
- Переменные ссылочных типов хранят лишь ссылку на адрес в памяти, по которому хранится значение (объект). Экземпляры ссылочных типов располагаются в куче (за исключением случая когда речь идет о указателях). Ссылочные типы делятся на самоописывающиеся типы, указатели и интерфейсы. Тип ссылочного типа может быть определен по значению самоописывающего типа. Самоописывающие типы делятся на массивы и классы. Классы в свою очередь делятся на пользовательские классы, упаковочные (boxed) значимые типы и делегаты.
Нижеследующий пример, написанный на языке Visual Basic .NET, демонстрирует различие между ссылочными типами и значимыми типами:
Imports System
Class Class1
Public Value As Integer = 0
End Class 'Class1
Class Test
Shared Sub Main()
Dim val1 As Integer = 0
Dim val2 As Integer = val1
val2 = 123
Dim ref1 As New Class1()
Dim ref2 As Class1 = ref1
ref2.Value = 123
Console.WriteLine("Значения: {0}, {1}", val1, val2)
Console.WriteLine("Ссылки: {0}, {1}", ref1.Value, ref2.Value)
End Sub 'Main
End Class 'Test
Вышеприведенный пример выводит следующее:
Значения: 0, 123 Ссылки: 123, 123
Упаковка
Значение значимого типа может быть преобразовано в значение ссылочного типа путём применения к нему процедуры упаковки (боксинга, англ. boxing). При этом значение переносится в кучу, и возвращается управляемая ссылка на область кучи содержащую это значение. Как видно из примера приведенного ниже, в C# нет необходимости указывать компилятору, что необходимо упаковать Int32-значение, превратив его тем самым в объект, поскольку компилятор C# сам выявляет такую необходимость и вставляет соответствующий код (IL). Однако это не относится к возможностям среды выполнения, а является поведением компилятора. Так в языке F# упаковка производится только если программист явно указал её необходимость.
Int32 x = 10;
object o = x ; // Неявная упаковка
Console.WriteLine("Объект o = {0}",o); // печатает 10
Однако, Int32 всегда может быть упакован явным образом, как показано ниже:
Int32 x = 10;
object o = (object) x; // Явная упаковка
Console.WriteLine("Объект o = {0}",o); // печатает 10
Распаковка
Процесс, обратный упаковке называется распаковкой (англ. unboxing). Нижеследующий пример демонстрирует как в языке C# распаковать запакованный до этого значимый тип.
Int32 x = 5;
object o1 = x; // Неявная упаковка
x = (int)o1; // Явная распаковка
Необходимо отметить, что в данном пример распаковка требует явного приведения типов. Это связано с тем, что запакованное значение имеет тип object, а распаковка требует указания конкретного типа. Начиная с C# 4.0 вместо типа object можно использовать тип dynamic, что позволяет обходиться без явного приведения типов.
dynamic x = 42;
int y = x; // Неявная распаковка
См. также
- .NET Framework
- Блит-типы
- Common Language Infrastructure
Примечания
Ссылки
- Common Type System (англ.)
- .NET Framework Class Library Overview (англ.)
- Boxing and Unboxing (C# Programming Guide) (рус.)