Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ооп теория

.pdf
Скачиваний:
19
Добавлен:
14.02.2015
Размер:
3.58 Mб
Скачать

создание исполнительной среды CLR. С ее появлением процесс написания и выполнения приложений становится принципиально другим. Но обо всем по порядку.

ДВУХЭТАПНАЯ КОМПИЛЯЦИЯ. УПРАВЛЯЕМЫЙ МОДУЛЬ И УПРАВЛЯЕМЫЙ КОД

Компиляторы языков программирования, включенные в Visual Studio .Net,

создают модули на промежуточном языке MSIL (Microsoft Intermediate Language), называемом далее просто - IL. Фактически компиляторы создают так называемый управляемый модуль - переносимый исполняемый файл

(Portable Executable или PE-файл). Этот файл содержит код на IL и

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

Framework .Net - мы еще будем говорить неоднократно. В зависимости от выбранного типа проекта, PE-файл может иметь расширения exe, dll, mod

или mdl.

Заметьте, PE-файл, имеющий расширение exe, хотя и является exe-файлом,

но это не совсем обычный исполняемый Windows файл. При его запуске он распознается как специальный PE-файл и передается CLR для обработки.

Исполнительная среда начинает работать с кодом, в котором специфика исходного языка программирования исчезла. Код на IL начинает выполняться под управлением CLR (по этой причине код называется управляемым). Исполнительную среду можно рассматривать как своеобразную виртуальную IL-машину. Эта машина транслирует "на лету"

требуемые для исполнения участки кода в команды реального процессора,

который в действительности и выполняет код.

ВИРТУАЛЬНАЯ МАШИНА

11

Отделение каркаса от студии явилось естественным шагом. Каркас

Framework .Net перестал быть частью студии, а стал надстройкой над операционной системой. Теперь компиляция и создание PE-модулей на IL

отделены от выполнения, и эти процессы могут быть реализованы на разных платформах. В состав CLR входят трансляторы JIT (Just In Time Compiler),

которые и выполняют трансляцию IL в командный код той машины, где установлена и функционирует исполнительная среда CLR. Конечно, в

первую очередь Microsoft реализовала CLR и FCL для различных версий

Windows, включая Windows 98/Me/NT 4/2000, 32 и 64-разрядные версии

Windows XP и семейство .Net Server. Для операционных систем Windows CE

и Palm разработана облегченная версия Framework .Net.

В 2001 году ECMA (Европейская ассоциация производителей компьютеров)

приняла язык программирования C#, CLR и FCL в качестве стандарта, так что Framework .Net уже функционирует на многих платформах, отличных от

Windows. Он становится свободно распространяемой виртуальной машиной.

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

Microsoft использовала получивший широкое признание опыт виртуальной машины Java, улучшив процесс за счет того, что, в отличие от Java,

промежуточный код не интерпретируется исполнительной средой, а

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

Следует отметить, что CLR, работая с IL-кодом, выполняет достаточно эффективную оптимизацию и, что не менее важно, защиту кода. Зачастую

12

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

ДИЗАССЕМБЛЕР И АССЕМБЛЕР

Если у вас есть готовый PE-файл, то иногда полезно анализировать его IL-

код и связанные с ним метаданные. В состав Framework SDK входит дизассемблер - ildasm, выполняющий дизассемблирование PE-файла и показывающий метаданные, а также IL-код с комментариями в наглядной форме. Мы иногда будем пользоваться результатами дизассемблирования. У

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

C:\Program Files\Microsoft Visual Studio .Net\ FrameworkSDK\Bin\ildasm.exe

Профессионалы, предпочитающие работать на низком уровне, могут программировать на языке ассемблера IL. В этом случае в их распоряжении будет вся мощь библиотеки FCL и все возможности CLR. У меня на компьютере путь к папке, где находится ассемблер, следующий:

C:\WINDOWS\Microsoft.Net\Framework\v1.1.4322\ilasm.exe

В этом курсе к ассемблеру мы обращаться не будем - я упоминаю о нем для полноты картины.

МЕТАДАННЫЕ

Переносимый исполняемый PE-файл является самодокументируемым файлом и, как уже говорилось, содержит и код, и метаданные, описывающие

13

код. Файл начинается с манифеста и включает в себя описание всех классов,

хранимых в PE-файле, их свойств, методов, всех аргументов этих методов -

всю необходимую CLR информацию. Поэтому помимо PE-файла не требуется никаких дополнительных файлов и записей в реестр - вся нужная информация извлекается из самого файла. Среди классов библиотеки FCL

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

самодокументированию уделяется большое внимание.

Мы увидим также, что при проектировании класса программист может создавать собственные атрибуты, добавляемые к метаданным PE-файла.

Клиенты этого класса могут, используя класс Reflection, получать эту дополнительную информацию, и на ее основании принимать соответствующие решения.

На рис. 1.1 показаны результаты дизассемблирования PE-файла простого консольного приложения с именем Account, включающего три класса:

Account, Testing и Class1. Дизассемблер структурирует информацию,

хранимую в метаданных, и показывает ее в типичном формате дерева. Как обычно, это дерево можно сжимать или раскрывать, демонстрируя детали класса. Значки, приписываемые каждому узлу дерева, характеризуют тип узла - класс, свойство, метод, описание. Двойной щелчок кнопки мыши на этом узле позволяет раскрыть его. При раскрытии метода можно получить его код. На рис. 1.1 показан код метода add из класса Account.

14

Рис. 1.1. Пример структуры PE-файла, задающего сборку

СБОРЩИК МУСОРА - Garbage Collector - И Управление Памятью

Еще одной важной особенностью построения CLR является то, что исполнительная среда берет на себя часть функций, традиционно входящих в ведение разработчиков трансляторов, и облегчает тем самым их работу. Один из таких наиболее значимых компонентов CLR - сборщик мусора (Garbage

Collector). Под сборкой мусора понимается освобождение памяти, занятой объектами, которые стали бесполезными и не используются в дальнейшей работе приложения. В ряде языков программирования (классическим примером является язык C/C++) память освобождает сам программист, в

явной форме отдавая команды как на создание, так и на удаление объекта. В

этом есть своя логика - "я тебя породил, я тебя и убью". Однако можно и нужно освободить человека от этой работы. Неизбежные ошибки

программиста при работе с памятью тяжелы по последствиям, и их крайне

15

тяжело обнаружить. Как правило, объект удаляется в одном модуле, а

необходимость в нем обнаруживается в другом, далеком модуле.

Обоснование того, что программист не должен заниматься удалением объектов, а сборка мусора должна стать частью исполнительной среды,

появилось достаточно давно. Наиболее полно оно обосновано в работах Бертрана Мейера и в его книге "Object-Oriented Construction Software", первое издание которой появилось еще в 1988 году.

В CLR эта идея реализована в полной мере. Задача сборки мусора снята не только с программистов, но и с разработчиков трансляторов, она решается в нужное время и в нужном месте - исполнительной средой, ответственной за выполнение вычислений. Здесь же решаются и многие другие вопросы,

связанные с использованием памяти, в частности, проверяются возможные нарушения использования "чужой" памяти и другие нарушения, например, с

использованием нетипизированных указателей. Данные, удовлетворяющие требованиям CLR и допускающие сборку мусора, называются управляемыми данными.

Но, как же, спросите вы, быть с языком C++ и другими языками, где есть нетипизированные указатели, адресная арифметика, возможности удаления объектов программистом? Такие возможности сохранены и в языке C#. Ответ следующий - CLR позволяет работать как с управляемыми, так и с неуправляемыми данными. Однако использование неуправляемых данных регламентируется и не поощряется. Так, в C# модуль, использующий неуправляемые данные (указатели, адресную арифметику), должен быть помечен как небезопасный (unsafe), и эти данные должны быть четко зафиксированы. Об этом мы еще будем говорить при рассмотрении языка C#

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

16

ИСКЛЮЧИТЕЛЬНЫЕ СИТУАЦИИ

Что происходит, когда при вызове некоторой функции (процедуры)

обнаруживается, что она не может нормальным образом выполнить свою работу? Возможны разные варианты обработки такой ситуации. Функция может возвращать код ошибки или специальное значение типа HResult,

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

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

языке C# выбрасывание исключений, их дальнейший перехват и обработка -

основной рекомендуемый способ обработки исключительных ситуаций.

СОБЫТИЯ

У CLR есть свое видение того, что представляет собой тип. Есть формальное описание общей системы типов CTS - Common Type System. В

соответствии с этим описанием, каждый тип, помимо полей, методов и свойств, может содержать и события. При возникновении событий в процессе работы с тем или иным объектом данного типа посылаются сообщения, которые могут получать другие объекты. Механизм обмена сообщениями основан на делегатах - функциональном типе. Надо ли говорить, что в язык C# встроен механизм событий, полностью согласованный с возможностями CLR. Мы подробно изучим все эти механизмы, рассматривая их на уровне языка.

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

CLR созданы на основании практики существующих языков

17

программирования. Но уже созданная исполнительная среда, в свою очередь,

влияет на языки, ориентированные на использование CLR. Поскольку язык

C# создавался одновременно с созданием CLR, то, естественно, он стал языком, наиболее согласованным с исполнительной средой, и средства языка напрямую отображаются в средства исполнительной среды.

ОБЩИЕ СПЕЦИФИКАЦИИ И СОВМЕСТИМЫЕ МОДУЛИ

Уже говорилось, что каркас Framework .Net облегчает межязыковое взаимодействие. Для того чтобы классы, разработанные на разных языках,

мирно уживались в рамках одного приложения, для их бесшовной отладки и возможности построения разноязычных потомков они должны удовлетворять некоторым ограничениям. Эти ограничения задаются набором общеязыковых спецификаций - CLS (Common Language Specification). Класс,

удовлетворяющий спецификациям CLS, называется CLS-совместимым. Он доступен для использования в других языках, классы которых могут быть клиентами или наследниками совместимого класса.

Спецификации CLS точно определяют, каким набором встроенных типов можно пользоваться в совместимых модулях. Понятно, что эти типы должны быть общедоступными для всех языков, использующих Framework

.Net. В совместимых модулях должны использоваться управляемые данные и выполняться некоторые другие ограничения. Заметьте, ограничения касаются только интерфейсной части класса, его открытых свойств и методов.

Закрытая часть класса может и не удовлетворять CLS. Классы, от которых не требуется совместимость, могут использовать специфические особенности языка программирования.

На этом я закончу обзорное рассмотрение Visual Studio .Net и ее каркаса

Framework .Net. Одной из лучших книг, подробно освещающих эту тему,

18

является книга Джеффри Рихтера, переведенная на русский язык: "Программирование на платформе .Net Framework". Крайне интересно, что для Рихтера языки являются лишь надстройкой над каркасом, поэтому он говорит о программировании, использующем возможности исполнительной среды CLR и библиотеки FCL.

19

Тема 2. ЯЗЫК C# И ПЕРВЫЕ ПРОЕКТЫ.

СОДЕРЖАНИЕ ЛЕКЦИИ:

СОЗДАНИЕ C#

ВИДЫ ПРОЕКТОВ КОНСОЛЬНЫЙ ПРОЕКТ

o WINDOWS-ПРОЕКТ

o НАЧАЛО НАЧАЛ - ТОЧКА "БОЛЬШОГО ВЗРЫВА"

o ВЫПОЛНЕНИЕ ПРОЕКТА ПО УМОЛЧАНИЮ ПОСЛЕ

"БОЛЬШОГО ВЗРЫВА"

o ПРОЕКТ WINDOWSHELLO

20