.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)
<p>Определение и реализация интерфейсов</p>

Как бы это странно ни выглядело, типы интерфейса определяются в 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{}

<p>Определение перечней</p>
Перейти на страницу:

Похожие книги