C# 4.0 полное руководство - 2011
Шрифт:
Рассмотрим подробнее порядок вызова методов. Сначала создается список методов. Затем в цикле foreach извлекаются сведения об их параметрах. Далее каждый метод вызывается с указанием соответствующего типа и числа аргументов в последовательном ряде условных операторов if/else. Обратите особое внимание на перегрузку метода Set в приведенном ниже фрагменте кода.
if(m.Name.CompareTo("Set")==0 &&
pi(0].ParameterType == typeof(int)) {
object[] args = new object[2]; args[0] = 9; args[l] = 18;
m.Invoke(reflectOb, args);
}
else if(m.Name.CompareTo("Set")==0 &&
pi[0].ParameterType == typeof(double)) {
object[] args = new object[2]; args[0] = 1.12; args[1 ] = 23.4; m.Invoke(reflectOb, args);
}
Если
Получение конструкторов конкретного типа
В предыдущем примере при вызове методов, определенных в классе MyClass, преимущества рефлексии не использовались, поскольку объект типа MyClass создавался явным образом. В таком случае было бы намного проще вызвать для него методы обычным образом. Но сильные стороны рефлексии проявляются наиболее заметно лишь в том случае, если объект создается динамически во время выполнения. И для
этого необходимо получить сначала список конструкторов, а затем экземпляр объекта заданного типа, вызвав один из этих конструкторов. Такой механизм позволяет получать во время выполнения экземпляр объекта любого типа, даже не указывая его имя в операторе объявления.
Конструкторы конкретного типа получаются при вызове метода GetConstructors для объекта класса Туре. Ниже приведена одна из наиболее часто используемых форм этого метода.
Constructorlnfo[] GetConstructors
Метод GetConstructors возвращает массив объектов класса Constructorlnfo, описывающих конструкторы.
Класс Constructorlnfo является производным от абстрактного класса MethodBase, который в свою очередь наследует от класса Memberlnf о. В нем также определен ряд собственных методов. К их числу относится интересующий нас метод GetConstructors , возвращающий список параметров, связанных с конструктором. Этот метод действует таким же образом, как и упоминавшийся ранее метод GetParameters , определенный в классе Methodlnf о.
Как только будет обнаружен подходящий конструктор, для создания объекта вызывается метод Invoke ,
object Invoke(object[] parameters)
Любые аргументы, которые требуется передать методу, указываются в массиве parameters. Если же аргументы не нужны, то вместо массива parameters указывается пустое значение (null). Но в любом случае количество элементов массива parameters должно совпадать с количеством передаваемых аргументов, а типы аргументов — с типами параметров. Метод Invoke возвращает ссылку на сконструированный объект.
В приведенном ниже примере программы рефлексия используется для создания экземпляра объекта класса MyClass.
// Создать объект с помощью рефлексии.
using System;
using System.Reflection;
class MyClass { int x; int y;
l
public MyClass(int i) {
Console.WriteLine("Конструирование класса MyClass(int, int). "); x = у = i;
}
public MyClass(int i, int j) {
Console.WriteLine("Конструирование класса MyClass(int, int). "); x = i;
У = j;
Show ;
public int Sum {
return x+y;
}
public bool IsBetween (int i) {
if((x < i) && (i < y)) return true; else return false;
}
public void Set(int a, int b) {
Console.Write("В методе Set (int, int). ") ; x = a;
У = b;
Show ;
}
// Перегрузить метод Set.
public void Set(double a, double b) {
Console.Write("В методе(double, double). ");
x = (int) a; у = (int) b;
Show;
}
public void Show {
Console.WriteLine("Значение x: {0}, значение у: {1}", x, у);
}
}
class InvokeConsDemo { static void Main {
Type t = typeof(MyClass); int val;
// Получить сведения о конструкторе.
Constructorlnfo[] ci = t.GetConstructors;
Console.WriteLine("Доступные конструкторы: "); foreach(Constructorlnfo с in ci) {