Россия, Челябинск, Южно-Уральский Государственный Университет (НИУ) |
Введение и обзор платформы .NET
Основные черты MSIL
MSIL можно рассматривать как ассемблер некоторой виртуальной машины. Это нетипичный ассемблер, так как он обладает многими конструкциями, характерными для языков более высокого уровня: например, в нем есть инструкции для описания пространств имен, классов, вызовов методов, свойств, событий и исключительных ситуаций. Кроме того, MSIL является стековой машиной со статической проверкой типов; это позволяет отслеживать некоторые типичные ошибки.
MSIL представляет собой дополнительный уровень абстракции, позволяющий легко справляться с переносом кода с одной платформы на другую, в том числе, и с изменением разрядности платформы: в отличие от Java bytecode MSIL не завязан на 32 бита или какую-либо другую фиксированную разрядность. В данный момент существуют версии MSIL для мобильных 16-разрядных устройств (.NET Compact Framework), стандартная 32-разрядная версия и специальная версия для работы с получающими все более широкое распространение 64-разрядными устройствами.
Отметим, что MSIL сохраняет достаточно много информации об именах, использованных в исходной программе: имена классов, методов и исключительных ситуаций сохраняются и могут быть извлечены при обратном ассемблировании. Однако извлечение из MSIL исходных текстов путем дизассемблирования вряд ли имеет смысл, так как имена локальных переменных, констант и параметров сохраняются только в отладочной версии.
Пример кода на MSIL
.class auto ansi Point extends ['mscorlib']System.Object { .field private int32 m_x .field private int32 m_y .method public specialname rtspecialname instance void .ctor() il managed { // Code size 21 (0x15) .maxstack 2 IL_0000: ldarg.0 IL_0001: call instance void ['mscorlib']System.Object::.ctor() IL_0006: ldarg.0 IL_0007: ldc.i4.0 IL_0008: stfld int32 Point::m_y IL_000d: ldarg.0 IL_000e: ldc.i4.0 IL_000f: stfld int32 Point::m_x IL_0014: ret } // end of method 'Point::.ctor'
На слайде приведен фрагмент MSIL-кода, сгенерированный по следующему классу на С#:
class Point { private int m_x, m_y; public Point() { m_x = m_y = 0; } }
В сгенерированном коде можно найти описание класса Point и тот факт, что он унаследован от System.Object, описание закрытых переменных типа Int32 m_x и m_y (отметим, что их имена сохраняются при обратном ассемблировании) и, наконец, конструктор класса Point.
На начальном этапе знакомства с .NET изучение сгенерированного MSIL-кода представляется весьма полезным, так что рекомендуем слушателям самостоятельно ознакомиться с утилитой ILDasm.
Базовая модель .NET
В основе .NET лежит единая объектно-ориентированная модель классов, в которой все классы унаследованы от базового класса Object. Классы разбиты на пространства имен для избежания накладок при совпадении имен. Основные сервисы .NET сосредоточены в пространстве имен System (например, там находится упоминавшийся выше класс Object ).
Пространства имен имеют много уровней вложенности (например, System.WinForms или System.Web.UI.WebControls ). На следующем слайде мы приведем часть иерархии классов .NET.
Программисты могут создавать собственные пространства имен для своих классов или пользоваться уже существующими классами, расширяя их функциональность путем наследования и переопределения методов.
Модель платформы .NET может существенно упростить разработку приложений по сравнению с программированием для Windows-платформ, где практически вся функциональность предоставлялась разработчику как неструктурированный набор функций в Windows API.
Иерархия классов (отрывок)
На слайде приведен отрывок из иерархии классов .NET. Несмотря на то, что идея сведения всех объектов в единую иерархию не нова (одним из первых языков с единой иерархией объектов был SmallTalk, затем подобный прием был использован в Java), отличительной особенностью платформы .NET является то, что в .NET единая модель объектов распространяется сразу на все языки программирования.
Системные классы становятся единственным методом взаимодействия программы с внешним миром для управляемого кода. Одним из следствий этого является необходимость переписывания всего ввода/вывода для существующих приложений, которые должны быть интегрированы в .NET. Это можно делать поэтапно, так как практически вся функциональность предыдущих версий языка поддержана в .NET специальными классами в целях обратной совместимости. Единственным заметным исключением является Visual Basic.NET, в котором необходимо целиком переделывать внешний вид форм путем использования классов из System.WinForms.
Понятие сборки
В платформе .NET появилось новое понятие - сборка (assembly). В первом приближении сборку можно воспринимать как аналог EXE или DLL; более того, в случае приложения, состоящего из одного файла, сборка даже имеет расширение .exe или .dll. Несмотря на это сходство, сборка содержит существенно больше информации о приложении, чем традиционные исполняемые файлы.
Причиной появления понятия сборки можно считать трудности установки Windows-приложений. Обычное Windows-приложение состоит из множества файлов - запускаемые модули, библиотеки, дополнительные файлы и т.п. Помимо этого, при установке некоторых приложений (особенно COM-компонент) необходимо записывать в реестр Windows сведения о нахождении и способе вызова. Наконец, многие приложения использовали разделяемые DLL, что зачастую приводило к проблемам при установке более новых версий этой DLL.
Понятие сборки было введено для того, чтобы решить эти проблемы. Сборка представляет собой набор файлов, модулей и дополнительной информации, которые должны обеспечить простую установку приложения и последующую работу. Таким образом, можно говорить и о том, что повторное использование приложений может быть реализовано с помощью интеграции различных сборок.