Введение в MSIL - Часть 3: Определение типов — Архив WASM.RU
В этой части я объясню, как задаются типы.
Вот минимальный ссылочный тип под названием House ("дом", - прим. пер.).
Код (Text):
.class Kerr.RealEstate.House { .method public void .ctor() { .maxstack 1 ldarg.0 // push "this" instance onto the stack call instance void [mscorlib]System.Object::.ctor() ret } }Это очень простой тип. Обратите внимание, что вы должны объявить конструктор для ссылочного типа. В отличии от таких языков как C# и C++, ассемблер IL не будет генерировать для вас конструктор автоматически.
Типы задаются с помощью директивы .class, за которой следует заголовок типа. Ключевое слово class используется вместо более интуитивно понятного type в силу исторических причин. Когда вы встречаете в исходном MSIL-коде слово class, просто читайте его как type. Заголовок типа состоит из определённого количества аттрибутов, за которым следует имя типа, который вы определяете. Чтобы задать эквивалент статического класса C#, вы можете написать следующее:
Код (Text):
.class abstract sealed Kerr.RealEstate.MortgageCalculator { /* members */ }abstract и sealed - это атрибуты типа. Нельзя сделать экземпляр абстрактного типа, а запечатанный (sealed) тип не может иметь подтипы. Есть атрибуты, которые служать для контроля видимости, такие как public и private. Есть атрибуты для контроля местоположения поля (field layout), такие как auto и sequential. Полный лист атрибутов можно узнать в спецификации CLI. Многие атрибуты применяются автоматически, что экономит на печати символов. К счастью, эти атрубты по умолчанию достаточно интуитивны, так что вы познакомитесь с ними достаточно быстро. Например, расширение System.ValueType из сборки mscorlib задаёт новый тип значений. Так как CLI требует, что типы значений были запечаны, ассемблер IL автоматически присвоит этот атрибут.
Имя типа в вышеприведённом примере было Kerr.RealEstate.MortgageCalculator. CLI не распознаёт пространства имён сами по себе, скорее речь идёт об использовании полного имени типа. Применённый выше синтаксис поддерживается ассемблером IL, который поставляется с .NET Framework версии 2.0. Если вы работаете с версией 1.x, тогда вам придётся применить директиву .namespace так. как это показано ниже. Обратите внимание, что этот синтаксис также поддерживается в версии 2.0.
Код (Text):
.namespace Kerr.RealEstate { .class abstract sealed MortgageCalculator { /* members */ } }После имени типа у вас есть возможность задать базовый тип. Ключевое слово extend применяется именно с этой целью. Если базовый тип не задан, ассемблер IL автомтически сделает так, что тип будет наследоватья от System.Object из сборки mscorlib. И, наконец, в заголовке типа могут быть указан список интерфейсов, которые будут реализованы в типе и его потомках.
Код (Text):
.class Kerr.RealEstate.RoomList extends [System.Windows.Forms]System.Windows.Forms.ListView implements Kerr.IView { /* members */ }В этом примере у типа Kerr.RealEstate.RoomList есть базовый тип System.Windows.Forms.ListView, заданный в сборке System.Windows.Forms. Помните, что CLI требует от каждого пользовательского типа расширять ровно один другой тип. Roomlisе также реализует интерфейсный тип Kerr.IView.
С помощью этого введения, вы теперь должны суметь задавать более интересные типы. Чтобы определить интерфейс, просто используйте атрибут interface в заголовке типа. Если вам нужен тип значения, известный в C# как struct, просто расширет тип System.ValueType из сборки mscorlib. Теперь вы видите, почему название директивы .class, возножно, далеко не самое лучшее.
© Кенни Керр, пер. AquilaКод (Text):
.class interface Kerr.IView { /* members */ } .class Kerr.RealEstate.HouseData extends [mscorlib]System.ValueType { /* members */ }
Введение в MSIL - Часть 3: Определение типов
Дата публикации 6 авг 2006