Рефлексия
31C# --- Сборки .NET --- Рефлексия
В мире .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() | Этот метод позволяет выполнять "позднее связывание" для заданного элемента |