Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Метаданные и получение информации о типах






При создании сборки в неё помещаются метаданные, которые являются описанием всех типов в сборке и их элементов. Программист может работать с метаданными, используя специальный механизм, называемый отражением (reflection). Главные элементы, которые необходимы для использования возможностей отражения – это класс System.Type и типы из пространств имён System.Reflection и System.Reflection.Emit.

Класс Type служит для хранения информации о типе. Существует несколько способов получить объект этого класса:

1. Вызвать у объекта метод GetType(). Данный метод определён на уровне System.Object, а значит, присутствует у любого объекта:

Foo foo = new Foo(); // Foo – это некий класс

Type t = foo.GetType();

2. Использовать статический метод Type.GetType(), которому передаётся имя типа в виде строки (имя должно быть полным, то есть включать пространство имён):

Type t = Type.GetType(" SomeNamepace.Foo");

3. Использовать операцию C# typeof, аргументом которой является тип:

Type t = typeof (Foo);

Операцию typeof можно применять к массивам и универсальным шаблонам. Причём в последнем случае допускается использовать как сконструированный тип, так и исходный тип-шаблон (обратите внимание на синтаксис записи универсального шаблона).

Type t1 = typeof (int[]);

Type t2 = typeof (char[, ]);

Type t3 = typeof (List< int>); // сконструированный тип

Type t4 = typeof (List< >); // универсальный тип

Свойства класса Type позволяют узнать имя типа, имя базового типа, является ли тип универсальным, в какой сборке он размещается и другую информацию. Кроме этого, Type имеет специальные методы, возвращающие данные о полях типа, свойствах, событиях, методах и их параметрах.

Рассмотрим пример получения информации о типе. Будем анализировать примитивный тип System.Int32:

Type t = typeof (Int32);

Console.WriteLine(" Full name = " + t.FullName);

Console.WriteLine(" Base type is = " + t.BaseType);

Console.WriteLine(" Is sealed = " + t.IsSealed);

Console.WriteLine(" Is class = " + t.IsClass);

Console.WriteLine(" Is primitive = " + t.IsPrimitive);

foreach (Type iType in t.GetInterfaces())

{

Console.WriteLine(iType.Name);

}

foreach (FieldInfo fi in t.GetFields())

{

Console.WriteLine(" Field = " + fi.Name);

}

foreach (PropertyInfo pi in t.GetProperties())

{

Console.WriteLine(" Property = " + pi.Name);

}

foreach (MethodInfo mi in t.GetMethods())

{

Console.WriteLine(" Method Name = " + mi.Name);

Console.WriteLine(" Method Return Type = " + mi.ReturnType);

foreach (ParameterInfo pr in mi.GetParameters())

{

Console.WriteLine(" Parameter Name = " + pr.Name);

Console.WriteLine(" Type = " + pr.ParameterType);

}

}

Как показывает пример, информация об элементах типа хранится в объектах классов FieldInfo, PropertyInfo, MethodInfo и т. п. Эти классы находятся в пространстве имён System.Reflection. Их иерархия показана на рис. 9.

Рис. 9. Иерархия классов для представления элементов типа.

Отметим, что код примера покажет данные только об открытых элементах типа. Составом получаемой информации можно управлять, передавая в Get-методы дополнительные флаги перечисления System.Reflection.BindingFlags (табл. 16).

Таблица 16

Флаги BindingFlags, связанные с получением информации о типе

Флаг Описание
Default Отсутствие специальных флагов
IgnoreCase Игнорировать регистр имён получаемых элементов
DeclaredOnly Получить элементы, объявленные непосредственно в типе (игнорировать унаследованные элементы)
Instance Получить экземплярные элементы
Static Получить статические элементы
Public Получить открытые элементы
NonPublic Получить закрытые элементы
FlattenHierarchy Получить public и protected элементы у типа и у всех его предков

Type t = typeof (Int32);

var bf = BindingFlags.Public | BindingFlags.NonPublic |

BindingFlags.Static | BindingFlags.Instance;

FieldInfo[] fi = t.GetFields(bf);

Пространство имён System.Reflection содержит типы для получения информации и манипулирования сборкой и модулем сборки. При помощи класса Assembly можно получить информацию о сборке, при помощи класса Module – о модуле. Основные элементы этих классов перечислены в табл. 17 и табл. 18.

Таблица 17

Основные элементы класса Assembly

Имя элемента Описание
CreateInstance() Находит по имени тип в сборке и создаёт его экземпляр
FullName Строковое свойство с полным именем сборки
GetAssembly() Ищет в памяти и возвращает объект Assembly, который содержит указанный тип (статический метод)
GetCustomAttributes() Получает атрибуты сборки
GetExecutingAssembly() Возвращает сборку, которая содержит выполняемый в текущий момент код (статический метод)
GetExportedTypes() Возвращает public-типы, определённые в сборке
GetFiles() Возвращает файлы, из которых состоит сборка
GetLoadedModules() Возвращает все загруженные в память модули сборки
GetModule() Получает указанный модуль сборки
GetModules() Возвращает все модули, являющиеся частью сборки
GetName() Возвращает объект AssemblyName для сборки
GetReferencedAssemblies() Возвращает объекты AssemblyName для всех сборок, на которые ссылается данная сборка
GetTypes() Возвращает типы, определённые в сборке
Load() Статический метод, который загружает сборку по имени
LoadFrom() Статический метод; загружает сборку из указанного файла
LoadModule() Загружает внутренний модуль сборки в память

Таблица 18

Основные элементы класса Module

Имя элемента Описание
Assembly Свойство с указанием на сборку (объект Assembly) модуля
FindTypes() Получает массив классов, удовлетворяющих заданному фильтру
FullyQualifiedName Строка, содержащая полное имя и путь к модулю
GetType() Пытается выполнить поиск указанного типа в модуле
GetTypes() Возвращает все типы, определённые в модуле
Name Строка с коротким именем модуля

Продемонстрируем пример работы с классами Assembly и Module:

Assembly assembly = Assembly.GetExecutingAssembly();

Console.WriteLine(assembly.FullName);

foreach (Module module in assembly.GetModules())

{

Console.WriteLine(module.FullyQualifiedName);

foreach (Type type in module.GetTypes())

{

Console.WriteLine(type.FullName);

}

}


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.008 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал