Рефлексия

Рефлексия — это получение информации о типах во время выполнения програм­мы. Например, можно получить список всех классов и интерфейсов сборки, спи­сок элементов каждого из классов, список параметров каждого метода и т. д. Вся информация берется из метаданных сборки. Для использования рефлексии не­обходимы класс System.Type и типы пространства имен System.Reflection.

В классе Туре описаны методы, которые позволяют получить информацию о ти­пах. В пространстве имен System.Reflection описаны типы, поддерживающие Туре, а также классы, которые служат для организации позднего связывания и дина­мической загрузки сборок. Наиболее важные свойства и методы класса Туре приведены в табл. 12.1.

Таблица 12.1. Элементы класса Туре


Элемент Описание

IsAbstract, IsArray, Свойства, позволяющие получить

IsNestedPublic, IsClass, соответствующие характеристики конкретного

IsNestedPrivate, IsCOMObject, типа в программе (например, является ли он

IsEnum, Islnterface, IsPrimitive, абстрактным, является ли он массивом,

IsSealed, IsValueType классом и т. п.). Приведены не все свойства

GetConstructors, GetEvents, Методы, возвращающие массив с набором

GetFields, GetInterfaces, соответствующих элементов (конструкторов,

GetMethods, GetMembers, событий, полей и т. п.). Возвращаемое значение

GetNestedTypes, GetProperties соответствует имени метода, например, GetFields

возвращает массив типа FieldInfo, GetMethods — массив типа MethodInfo. Для каждого из методов есть парный ему (без символа S в конце имени), который предназначен для работы с одним заданным в параметре элементом (например, GetMethod и GetMethods)

FindMembers Метод возвращает массив типа MemberInfo на основе заданных

критериев поиска

GetType Метод возвращает объект типа Туре по имени, заданному в виде

строки

InvokeMember Метод используется для позднего связывания заданного элемента

Воспользоваться этими методами можно после создания экземпляра класса Туре. Поскольку это абстрактный класс, обычный способ создания объектов с помо­щью операции new неприменим, зато существуют три других способа:

1. В базовом классе object описан метод GetType, которым можно воспользоваться для любого объекта, поскольку он наследуется. Метод возвращает объект
типа Туре, например:

Monster X = new Monster(); Type t = X.GetType();

2. В классе Type описан статический метод GetType с одним параметром строкового типа, на место которого требуется передать имя класса (типа), например:

Type t = Type.GetType("Monster");

3. Операция typeof возвращает объект класса Туре для типа, заданного в качестве параметра, например:

Type t = typeof(Monster);

При использовании второго и третьего способов создавать экземпляр исследуе­мого класса нет необходимости.

Как видно из табл. 12.1, многие методы класса Туре возвращают экземпляры стан­дартных классов (например, Member Info). Эти классы описаны в пространстве имен System.Reflection. Наиболее важные из этих классов перечислены в табл. 12.2.

Таблица 12.2. Некоторые классы пространства имен System.Reflection


Тип Описание

Assembly Содержит методы для получения информации о сборке, а также для загрузки

сборки и выполнения с ней различных операций

AssemblyName Позволяет получать информацию о сборке (имя, версия, совместимость,

естественный язык и т. п.)

EventInfo Хранит информацию о событии

FieldInfo Хранит информацию о поле

MemberInfo Абстрактный базовый класс, определяющий общие элементы для классов

EventInfo, FieldInfo, MethodInfo и PropertyInfo

MethodInfo Хранит информацию о методе

Module Позволяет обратиться к модулю в многофайловой сборке

ParameterInfo Хранит информацию о параметре

PropertyInfo Хранит информацию о свойстве

В листинге 12.3 приведены примеры использования рассмотренных методов и классов для получения информации о классах библиотеки из листинга 12.1.

Листинг 12.3.Получение информации о классах

using System;

using System.Reflection;

namespace ConsoleApplication1

{

using MonsterLib;

class Class1

{

static void Info(Type t)

{

Console.WriteLine("======= Класс " + t.FullName);

if (t.IsAbstract)

Console.WriteLine("абстрактный");

if (t.IsClass)

Console.WriteLine("обычный");

if (t.IsEnum)

Console.WriteLine("перечисление");

Console.WriteLine("базовый класс " + t.BaseType);

Methodlnfo[] met = t.GetMethods();

foreach (MethodInfo m in met)

Console.WriteLine(m);

Console.WriteLine();

PropertyInfo[] prs = t.GetProperties();

foreach (Propertylnfo p in prs)

Console.WriteLine(p);

Console.WriteLine();

}

static void Main()

{

Type t = typeof(Spirit);

Info(t);

t = typeof(Monster);

Info(t);

t = typeof(Daemon);

Info(t);

}

}

}

Результат работы программы:

======= класс MonsterLib.Spirit

абстрактный

обычный

базовый класс System.Object

Void Passport()

Int32 GetHashCode()

Boolean Equals(System.Object)

System.String ToString()

System.Type GetType()

======= класс MonsterLib.Monster

обычный

базовый класс MonsterLib.Spirit

Void Passport()

Int32 GetHashCode()

Boolean Equals(System.Object)

System.String ToString()

Int32 get_Health()

Void set_Health(Int32)

Int32 get_Ammo()

Void set_Ammo(Int32)

System.String get_Name()

System.Type GetType()

Int32 Health

Int32 Ammo

System.String Name

======= Класс MonsterLib.Daemon

обычный

базовый класс MonsterLib.Monster

Void Passport()

Int32 GetHashCode()

Boolean Equals(System.Object)

System.String ToString()

Void Think()

Int32 get_Health()

Void set_Health(Int32)

Int32 get_Ammo()

Void set_Ammo(Int32)

System.String get_Name()

System.Type GetType()

Int32 Health

Int32 Ammo

System.String Name

Можно продолжить исследования дальше, например, получить параметры и воз­вращаемое значение каждого метода. Думаю, что принцип вам уже ясен. Напом­ню, что вся эта информация берется из метаданных сборки.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: