![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Метаданные и получение информации о типах
При создании сборки в неё помещаются метаданные, которые являются описанием всех типов в сборке и их элементов. Программист может работать с метаданными, используя специальный механизм, называемый отражением (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, связанные с получением информации о типе
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
Таблица 18 Основные элементы класса Module
Продемонстрируем пример работы с классами 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); } }
|