Необходимость в метаданных типов

79

Возможность полностью описывать типы (классы, интерфейсы, структуры, перечисления и делегаты) с помощью метаданных является одной из ключевых в платформе .NET. Во многих технологиях .NET, таких как сериализация объектов, удаленная работа, веб-службы XML и Windows Communication Foundation (WCF), эта возможность нужна для выяснения формата типов во время выполнения. Более того, в средствах обеспечения функциональной совместимости между языками, многочисленных службах компилятора и предлагаемой в IDE-среде функции IntelliSense везде за основу берется конкретное описание типа.

Невзирая на важность (а, возможно, и благодаря ей), метаданные не являются новинкой, поставляемой только в .NET Framework. В Java, CORBA и СОМ тоже применяются похожие концепции. Например, в СОМ для описания типов, содержащихся внутри сервера СОМ, используются специальные библиотеки типов СОМ (которые являются не более чем просто скомпилированным IDL-кодом). Как и в СОМ, в библиотеках кода в .NET поддерживаются метаданные типов, но эти метаданные, конечно же, синтаксически совершенно не похожи на IDL-метаданные из СОМ.

Вспомните, что утилита ildasm.exe позволяет просматривать метаданные всех содержащихся в сборке типов, для чего в ней нужно нажать комбинацию клавиш Ctrl+M. Если открыть в этой утилите любую из сборок *.dll или *.ехе и нажать Ctrl+M, можно увидеть метаданные всех содержащихся в ней типов, как показано на рисунке:

Метаданные сборки

На этом рисунке видно, что метаданные типов .NET отображаются в ildasm.exe очень подробно (в двоичном формате они гораздо компактнее). В действительности описание всех метаданных обычной сборки заняло бы несколько страниц. Однако вполне достаточно будет кратко рассмотреть только некоторые наиболее важные описания метаданных сборки.

Глубоко вдаваться в то, что обозначает синтаксис в каждом из приводимых фрагментов метаданных .NET, не стоит. Главное — понять, что метаданные .NET являются очень описательными и предусматривают перечисление каждого определенного внутри (или упоминаемого с помощью внешней ссылки) типа, который встречается в данной кодовой базе.

Каждый тип, который определен внутри текущей сборки, сопровождается маркером TypeDef #n (TypeDef — сокращение от type definition (определение типа)). Если описываемый тип предусматривает использование еще какого-то типа, определенного в другой сборке .NET, этот второй тип сопровождается маркером TypeRef #n (TypeRef — сокращение от type reference (ссылка на тип)). Маркер TypeRef, по сути, является указателем на полное определение метаданных соответствующего типа во внешней библиотеке. Вкратце, метаданные в .NET представляют собой ряд таблиц, в которых явным образом перечислены все определения типов (TypeDef) и типы, на которые они ссылаются (TypeRef), причем те и другие можно просматривать в специальном окне метаданных утилиты ildasm.exe.

Например в сборке fontinfo.dll, рассматривавшейся в предыдущем разделе, можно встретить подробное описание классов:

Метаданные определенного класса

Давайте рассмотрим полученные данные более подробно. Маркер TypDefName используется для описания имени данного типа, маркер Extends — для описания базового класса, который лежит в его основе (и каковым в данном случае является тип System.Object), а маркер Field #n — для описания каждого поля, которое входит в его состав. Маркеры Method #n содержат подробное описание инкапсулированных в классе методов.

В окне метаданных утилиты ildasm.exe можно также просматривать метаданные .NET, описывающие саму сборку, для обозначения которых используется маркер Assembly. Как показано в приведенном ниже (неполном) листинге, информация, документируемая внутри таблицы Assembly, совпадает с той, что можно просматривать через значок MANIFEST:

Метаданные сборки

И. наконец, последним интересным моментом относительно метаданных .NET является то, что внутри маркера User Strings обязательно документируются все присутствующие в кодовой базе строковые литералы:

Метаданные строковых литералов
Лучший чат для C# программистов