рис. 23.2.
.Типы,.используемые.приложениями.для.обхода.объектной.модели.отражения
Тип позволяет также находить реализуемые им интерфейсы (как это сделать,
я покажу позже). И из конструктора, метода, метода-аксессора свойства или метода
создания/удаления сообщения можно вызвать метод
GetParameters
, чтобы полу-
чить массив объектов
ParameterInfo
, которые информируют вас о типах параметров
658
Глава.23 .Загрузка.сборок.и.отражение
членов. Можно также запросить свойство
ReturnParameter
, чтобы получить объект
ParameterInfo
с подробной информацией о возвращаемом значении члена. Чтобы
получить набор параметров типа для обобщенных типов и методов, можно вызы-
вать метод
GetGenericArguments
. Наконец, чтобы получить набор нестандартных
атрибутов, примененных ко всем указанным сущностям, можно вызывать метод
GetCustomAttributes
.
Обращение к членам типов
Итак, вы знаете, как получить информацию о членах типа. Следующим шагом
должно стать обращение к одному из этих членов. Термин «обращение» в данном
случае зависит от разновидности члена. В табл. 23.2 указано, какие методы следует
вызывать в каждом конкретном случае.
таблица 23.2.
.Методы.обращения.к.членам.типов
тип
Описание
FieldInfo
Метод GetValue получает значение поля, метод SetValue — задает
его значение
ConstructorInfo
Метод Invoke создает экземпляр типа и вызывает конструктор
MethodInfo
Метод Invoke вызывает метод типа
PropertyInfo
Метод GetValue вызывает метод доступа get, метод SetValue —
метод доступа set для свойства
EventInfo
Метод AddEventHandler вызывает метод add, метод
RemoveEventHandler — метод remove для события
Тип
PropertyInfo
представляет информацию метаданных свойств (см. гла-
ву 10), поддерживая доступные только для чтения свойства
CanRead
,
CanWrite
и
PropertyType
. Эти свойства показывают, можно ли читать и записывать свойство,
а также его тип данных. У
PropertyInfo
также есть свойства
GetMethod
и
SetMethod
,
возвращающие объекты
MethodInfo
для методов чтения и записи значения свой-
ства. Методы
GetValue
и
SetValue
типа
PropertyInfo
существуют для удобства,
их внутренний код получает соответствующие объекты
MethodInfo
и вызывает
их. Для поддержки параметрических свойств (индексаторов С#) методы
SetValue
и
GetValue
предоставляют параметр
index
типа
Object
[]
.
Тип
EventInfo
представляет метаинформацию событий (см. главу 11). Он
поддерживает доступное только для чтения свойство
EventHandlerType
, которое
возвращает объект
Type
для делегата события. У
EventInfo
также есть свойства
AddMethod
и
RemoveMethod
, которые возвращают объекты
MethodInfo
для методов
добавления и удаления делегатов. Чтобы добавить или удалить делегата, можно
659
Нахождение.членов.типа.путем.отражения
обратиться с вызовом к этим объектам
MethodInfo
или же воспользоваться более
удобными методами
AddEventHandler
и
RemoveEventHandler
класса
EventInfo
.
В приведенном далее приложении-примере демонстрируются разные способы
применения отражения для доступа к членам типа. Класс
SomeType
представляет
тип с различными членами: закрытым полем (
m_someField
), открытым конструк-
тором (
SomeType
), получающим аргумент типа
Int32
по ссылке, открытым методом
(
ToString
), открытым свойством (
SomeProp
) и открытым событием (
SomeEvent
).
При наличии определения типа
SomeType
я также могу предложить три разных
метода использования отражения для доступа к членам
SomeType
. Каждый метод
задействует отражение по-своему.
Метод
BindToMemberThenInvokeTheMember
демонстрирует привязку и после-
дующий вызов.
Метод
BindToMemberCreateDelegateToMemberThenInvokeTheMember
демонстри-
рует привязку с последующим созданием делегата, ссылающегося на объект или
член. Вызов через делегата выполняется очень быстро, и этот вариант позволяет
еще больше повысить производительность программного кода для случаев
многократного вызова одинаковых членов разными объектами.
Метод
UseDynamicToBindAndInvokeTheMember
демонстрирует использование
в языке С# примитивного типа
dynamic
(см. главу 5) с целью упрощения син-
таксиса доступа к членам. К тому же этот вариант может помочь добиться дей-
ствительно хорошей производительности программного кода для случаев вызова
одинаковых членов разными объектами, потому что связывание происходит один
раз для каждого типа и затем кэшируется таким образом, чтобы последующий
многократный вызов членов происходил быстро. Вы также можете использовать
этот вариант с целью вызова членов для объектов различных типов.
using System;
using System.Reflection;
using Microsoft.CSharp.RuntimeBinder;
using System.Linq;
// Класс для демонстрации отражения.
// У него есть поле, конструктор, метод, свойство и событие
internal sealed class SomeType {
private Int32 m_someField;
public SomeType(ref Int32 x) { x *= 2; }
public override String ToString() { return m_someField.ToString(); }
public Int32 SomeProp {
get { return m_someField; }
set {
if (value < 1)
throw new ArgumentOutOfRangeException("value");
m_someField = value;
}
public event EventHandler SomeEvent;
продолжение
660
Do'stlaringiz bilan baham: |