Рефлексия

31

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

Многие классы, поддерживающие рефлексию, входят в состав прикладного интерфейса .NET Reflection API, относящегося к пространству имен System.Reflection. Как и в любом другом пространстве имен, в System.Reflection (которое поставляется в составе сборки mscorlib.dll) содержится набор взаимосвязанных типов. Ниже описаны некоторые наиболее важные из этих типов:

Assembly

В этом абстрактном классе содержатся статические методы, которые позволяют загружать сборку, исследовать ее и производить с ней различные манипуляции

AssemblyName

Этот класс позволяет выяснить различные детали, связанные с идентификацией сборки (номер версии, информация о культуре и т.д.)

EventInfо

В этом абстрактном классе хранится информация о заданном событии

FieldInfo

В этом абстрактном классе хранится информация о заданном поле

MemberInfo

Этот абстрактный базовый класс определяет общее поведение для типов EventInfo, FieldInfo, MethodInfo и PropertyInfo

MethodInfo

В этом абстрактном классе содержится информация по заданному методу

Module

Этот абстрактный класс позволяет получить доступ к определенному модулю внутри многофайловой сборки

ParameterInfо

В этом классе хранится информация по заданному параметру

PropertyInfо

В этом абстрактном классе хранится информация по заданному свойству

Чтобы понять, каким образом использовать пространство имен System.Reflection для программного чтения метаданных .NET, необходимо сначала ознакомиться с классом System.Type.

Класс System.Type

Класс System.Type составляет ядро подсистемы рефлексии, поскольку он инкапсулирует тип данных. Он содержит многие свойства и методы, которыми можно пользоваться для получения информации о типе данных во время выполнения. Класс Type является производным от абстрактного класса System.Reflection.MemberInfo.

В классе MemberInfo определены приведенные ниже свойства, доступные только для чтения:

Свойство Описание
Type DeclaringType Тип класса или интерфейса, в котором объявляется отражаемый член
MemberType Тип члена. Это значение обозначает, является ли член полем, методом, свойством, событием или конструктором
int MetadataToken Значение, связанное к конкретными метаданными
Module Объект типа Module, представляющий модуль (исполняемый файл), в котором находится отражаемый тип
string Name Имя типа
Type ReflectedType Тип отражаемого объекта

Следует иметь в виду, что свойство MemberType возвращает тип MemberTypes — перечисление, в котором определяются значения, обозначающие различные типы членов. К их числу относятся следующие:

MemberTypes.Constructor
MemberTypes.Method
MemberTypes.Field
MemberTypes.Event
MemberTypes.Property

Следовательно, тип члена можно определить, проверив свойство MemberType. Так, если свойство MemberType имеет значение MemberTypes.Method, то проверяемый член является методом.

В класс MemberInfo входят два абстрактных метода: GetCustomAttributes () и IsDefined(). Оба метода связаны с атрибутами. Первый из них получает список специальных атрибутов, имеющих отношение к вызывающему объекту, а второй устанавливает, определен ли атрибут для вызывающего метода. В версию .NET Framework Version 4.0 внедрен метод GetCustomAttributesData(), возвращающий сведения о специальных атрибутах.

Класс System.Type имеет набор членов, которые могут применяться для изучения метаданных типа, и большинство из которых возвращает типы из пространства имен System.Reflection. Например, член Type.GetMethods() возвращает массив объектов типа MethodInfo, член Type.GetFields() — массив объектов типа FieldInfo. и т.д. Ниже приведен частичный список членов, которые поддерживает System.Type (полный перечень можно найти в документации .NET Framework 4.0 SDK):

Тип Описание
IsAbstract
IsArray
IsClass
IsCOMObject
IsEnum
IsGenericTypeDefinition
IsGeneriсParameter
Islnterface
IsPrimitive
IsNestedPrivate
IsNestedPublic
IsSealed
IsValueType
Эти свойства позволяют выяснять ряд основных деталей об интересующем типе (например, является ли он абстрактной сущностью, массивом, вложенным классом и т.д.)
GetConstructors()
GetEvents()
GetFields()
GetInterfaces()
GetMembers()
GetMethods()
GetNestedTypes()
GetProperties()
Эти методы позволяют получать массив представляющих интерес элементов (интерфейсов, методов, свойств и т.д.). Каждый из этих методов возвращает соответствующий массив (например, GetFields() возвращает массив FieldInfo, GetMethods () — массив MethodInfo и тд.). Следует иметь в виду, что каждый из них имеет также форму единственного числа (например, GetMethod(), GetProperty() и т.п.), которая позволяет извлекать только один элемент по имени, а не целый массив подобных элементов
FindMembers() Этот метод возвращает массив объектов типа MemberInfo на основе указанных критериев поиска
GetType() Этот статический метод возвращает экземпляр Type, обладающий указанным строковым именем
InvokeMember() Этот метод позволяет выполнять "позднее связывание" для заданного элемента
Лучший чат для C# программистов