Опубликован: 19.08.2004 | Уровень: для всех | Доступ: платный | ВУЗ: Национальный исследовательский ядерный университет «МИФИ»
Лекция 7:

Теория типов и типизация в .NET

Аннотация: В данной лекции будут рассмотрены вопросы, относящиеся к истории развития, идеологии, математическому основанию и обзору возможностей типизированной комбинаторной логики и теории типов - математической формализации, моделирующей типы выражений в языках программирования.
Ключевые слова: net, теория типов, типизированное исчисление, сегментация, типизация, сущность предметной области, строгая типизация, несоответствие типа, контроль соответствия типов, безопасность, тип, императивный язык, Pascal, FORTRAN, PL/I, сильная типизация, SML, выводимость типов, язык программирования, полиморфная типизация, время компиляции, compilation time, время выполнения, run time, Common Type System, класс, преобразование типов, иерархия типов, пространство имен, сборка, ссылочный тип, reference type, тип-значение, значение, ссылка, означивание, константы, связывание, подтип, элементарный тип, перечислимый тип, структурный тип, очередь, строковый тип, интерфейс, массив, делегат, USER, перечисления, символьные строки, потеря точности, побочный эффект, переполнение, иерархия, логическая структуризация, полное имя, коллизия обозначений, using, альтернативное имя, Visual Studio, команда, CTS, boxing, unboxing, список

Обсудим основы дисциплины типов в рамках .NET. Напомним, что история развития математических формализаций для типовых теорий изложена во вступительной лекции, а основа теории типов - в лекции 6.

Обобщим те преимущества, которые отличают языки программирования и формальные теории с типами.

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

Введение типизации облегчает и упорядочивает не только восприятие, но и управление предметной областью. Манипулирование типизированными элементами носит более целенаправленный характер, причем появляется возможность обрабатывать разнородные сущности предметной области различным образом, а однородные (или, точнее, однотипные) - единообразно.

Перейдем к языкам программирования и практике проектирования и реализации программных систем. В случае построения языка программирования по принципу строгой типизации несоответствия типов фиксируются до начала этапа выполнения программы (на этапе контроля соответствия типов в ходе трансляции), что гарантирует отсутствие семантических (смысловых) и логических ошибок и безопасность программного кода.

Напомним классификацию систем типизации в языках программирования.

Исторически наиболее распространенной для языков программирования является строгая типизация. При таком формировании системы типов в языке в любой момент существования любого языкового объекта существует однозначное соответствие между объектом и его типом. Другими словами, можно запрограммировать функцию, определяющую тип объекта, подобную ранее рассмотренной нами функции typeof языка программирования C#. Строго типизированными являются классические императивные языки программирования Pascal, FORTRAN, PL/I и др. Отметим, что классический вариант языка программирования C не является строго типизированным.

Сильная типизация необходима для обеспечения корректности связывания переменных со значениями до выполнения программы. Таким образом, каждое выражение языка программирования с сильной типизацией по успешном завершении анализа корректности типизации является корректно типизированным. Примером языка программирования с сильной типизацией может служить SML. Использование механизма выводимости типов гарантирует сильную типизацию даже при отсутствии строгости. Язык программирования, не имеющий сильной системы типизации, может быть назван языком со слабой типизацией.

Еще одним важным видом систем типизации языков программирования является полиморфная типизация. При таком подходе допустимы выражения переменного типа (скажем, функция упорядочения списка с заранее неопределенным типом элементов).

Иерархия типов в .NET

Рис. 18.1. Иерархия типов в .NET

Процедура контроля соответствия типов (type-checking) может быть реализована как во время компиляции (compile time), т.е. более безопасным образом, так и во время выполнения (run time) программы, что потенциально менее безопасно для программного кода.

Исследуем особенности управления типами в системе типизации Common Type System технологии Microsoft .NET.

Из соображений безопасности программного кода Microsoft .NET типы Common Type System, так же, как объекты и классы, могут использоваться только после инициализации. При этом необходимо учитывать особенности вызывающего метода, а также методов доступа get и изменения set.

Подобно конкретизации значений типов при определении значения типовой переменной, над элементами типов могут осуществляться преобразования из одного типа данных в другой (например, из строки в число или наоборот). При этом такие преобразования могут инициироваться как программистом (т.е. происходить явно), так и системой программирования (т.е. происходить неявным образом).

Иерархия типов в соотнесении с Microsoft .NET может быть представлена в форме той или иной совокупности (в частности, в виде пространства имен, файла или сборки ).

Как уже отмечалось, наиболее крупными и важными подкатегориями иерархической системы типизации в Microsoft .NET являются ссылочные типы (reference type) и типы-значения (value type).

Рассмотрим более подробно особенности реализации ссылочных типов и типов-значений в языке программирования C#.

Прежде всего, типы-значения, в отличие от ссылочных типов, содержат непосредственно объекты данных. Кроме того, типы-значения не могут быть пустыми (т.е. принимать значение null ).

Ссылочные типы, в противоположность типам-значениям, содержат не сами объекты, а лишь ссылки на них, и могут принимать значение null.

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

int i = 25;
string s = "John_Smith";

В первой строке программы происходит означивание целочисленной константы (т.е. типа-значения ), а во второй - строковой (т.е. типа-ссылки). В результате при выполнении первой строки программы происходит связывание со значением в памяти, а во втором - со ссылкой, т.е. указателем на область памяти.