.namespace MyNamespace {
.class public MyBaseClass {}
.class public MyDerivedClass extends MyNamespace.MyBaseClass {}
}
Вдобавок к атрибутам public и extends определение класса CIL может иметь множество дополнительных спецификаторов, задающих параметры видимости типа, размещения полей и т.д. В табл. 15.3 предлагаются описаний некоторых атрибутов, которые могут использоваться с директивой .class.
Таблица 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 interface IMyInterface {}
.class public MyBaseClass {}
// Теперь DerivedTestClass реализует IAmAnInterface.
class public MyDerivedClass
extends MyNamespace.MyBaseClass implements MyNamespace.IMyInterface {}
}
Как было показано в главе 7, интерфейсы могут выступать в качестве базовых интерфейсов в отношении других типов интерфейса, в результате чего создаются иерархии интерфейсов. Однако, вопреки вашим возможным догадкам, атрибут extends нельзя использовать для получения интерфейса А из интерфейса В. Атрибут extends используется только для указания базового класса типа. Чтобы расширить интерфейс, вы должны еще раз использовать атрибут implements.
// Расширение интерфейсов в терминах CIL.
.class public interface IMyInterface {}
.class public interface IMyOtherInterface implements MyNamespace.IMyInterface {}
Определение структур
Директива .class может использоваться и для определения CTS-структуры, если соответствующий тип расширяет System.ValueType. Кроме того, такая директива .class сопровождается атрибутом sealed (поскольку структура не может быть базовой по отношению к другим типам, характеризуемым значениями). Если вы попытаетесь сделать иначе, ilasm.exe сгенерирует ошибку компиляции.
// Структура всегда должна быть изолированной.
.class public sealed MyStruct extends [mscorlib]System.ValueType {}
Полезно знать о том, что CIL предлагает специальное сокращение для определения типа структуры. Если вы используете атрибут value, новый тип будет производным от [mscorlib] System.ValueType и получит атрибут sealed автоматически. Таким образом, можно определить MyStruct так.
// Сокращенная запись для определения структуры.
.class public value MyStruct{}
Определение перечней