Таблица 15.3.Атрибуты, которые могут использоваться с директивой .class
| Атрибут |
Описание |
| public, private, nested assembly, nested famandassem, nested family, nested famorassem, nested public, nested private |
В CIL определяется множество атрибутов, используемых для указании параметров видимости типа. Как видите, CIL предлагает целый ряд возможностей, не доступных в C# |
| abstract sealed |
Эти два атрибута можно добавить к директиве.class, чтобы определить абстрактный класс или изолированный класс, соответственно |
| auto sequential explicit |
Эти атрибуты используются для информирования CLR о том, как следует размещать поля данных в памяти. Для типов класса вполне подойдет вариант, используемый по умолчанию (auto) |
| extends implements |
Эти атрибуты позволяют определить базовый класс типа (с помощью extends) или реализовать интерфейс (с помощью implements) |
Определение и реализация интерфейсов
Как бы это странно ни выглядело, типы интерфейса определяются в CIL с помощью директивы .class. Но когда директива .сlass сопровождается атрибутом interface, соответствующий тип реализуется, как тип интерфейса CTS (Common Type System – общая система типов). После определения интерфейс можно привязать к типу класса или структуры с помощью CIL-атрибута implements.
.namespace MyNamespace {
// Определение интерфейса.
.class public interfaceIMyInterface {}
.class public MyBaseClass {}
// Теперь DerivedTestClass реализует IAmAnInterface.
class public MyDerivedClass
extends MyNamespace.MyBaseClass implementsMyNamespace.IMyInterface {}
}
Как было показано в главе 7, интерфейсы могут выступать в качестве базовых интерфейсов в отношении других типов интерфейса, в результате чего создаются иерархии интерфейсов. Однако, вопреки вашим возможным догадкам, атрибут extends нельзя использовать для получения интерфейса А из интерфейса В. Атрибут extends используется только для указания базового класса типа. Чтобы расширить интерфейс, вы должны еще раз использовать атрибут implements.
// Расширение интерфейсов в терминах CIL.
.class public interface IMyInterface {}
.class public interface IMyOtherInterface implementsMyNamespace.IMyInterface {}
Определение структур
Директива .class может использоваться и для определения CTS-структуры, если соответствующий тип расширяет System.ValueType. Кроме того, такая директива .class сопровождается атрибутом sealed (поскольку структура не может быть базовой по отношению к другим типам, характеризуемым значениями). Если вы попытаетесь сделать иначе, ilasm.exe сгенерирует ошибку компиляции.
// Структура всегда должна быть изолированной.
.class public sealedMyStruct extends [mscorlib] System.ValueType{}
Полезно знать о том, что CIL предлагает специальное сокращение для определения типа структуры. Если вы используете атрибут value, новый тип будет производным от [mscorlib] System.ValueType и получит атрибут sealed автоматически. Таким образом, можно определить MyStruct так.
// Сокращенная запись для определения структуры.
.class public valueMyStruct{}
Перечни .NET (как вы помните) получаются из класса System.Enum, производного от System.ValueType (и, таким образом, тоже должны быть изолированными). Чтобы определить перечень в терминах CIL, следует просто расширить [mscorlib]System.Enum.
// Перечень.
.class public sealedMyEnum extends [mscorlib] System.Enum{}
Как и для структур, для определения перечней имеется специальное сокращение, атрибут enum.
// Сокращенная запись для определения перечня.
.class public enumMyEnum {}
Замечание.Последний из фундаментальных типов данных .NET, делегат, тоже имеет специальное представление в CIL. Подробности можно найти в главе 6.
Компиляция файла CILTypes.il
Даже если вы не добавите никаких членов или иного программного кода в определенные вами типы, вы можете скомпилировать файл *.il в компоновочный блок DLL (иное просто невозможно, поскольку вы не указали метод Main()).
Откройте окно командной строки и введите следующую команду.
ilasm /dll CilTypes.il
После этого вы сможете открыть свой двоичный файл в ildasm.exe (рис. 15.4).
Рис. 15.4. Содержимое компоновочного блока CILTypes.dll
Проверив содержимое своего компоновочного блока, запустите для него peverify.exe. В результате будет выдан целый ряд сообщений об ошибках, поскольку все ваши типы пусты. Чтобы понять, как заполнить типы содержимым, мы должны сначала рассмотреть базовые типы данных CIL.
Читать дальше