Страница 258 из 502
В предыдущем примере при вызове методов, определенных в классе MyClass, преимущества рефлексии не использовались, поскольку объект типа MyClass создавался явным образом. В таком случае было бы намного проще вызвать для него методы обычным образом. Но сильные стороны рефлексии проявляются наиболее заметно лишь в том случае, если объект создается динамически во время выполнения. И для этого необходимо получить сначала список конструкторов, а затем экземпляр объекта заданного типа, вызвав один из этих конструкторов. Такой механизм позволяет получать во время выполнения экземпляр объекта любого типа, даже не указывая его имя в операторе объявления.
Конструкторы конкретного типа получаются при вызове метода GetConstructors() для объекта класса Туре. Ниже приведена одна из наиболее часто используемых форм этого метода.
<b>ConstructorInfo[] GetConstructors()</b>
Метод GetConstructors() возвращает массив объектов класса ConstructorInfo, описывающих конструкторы.
Класс ConstructorInfo является производным от абстрактного класса MethodBase, который в свою очередь наследует от класса Memberlnfо. В нем также определен ряд собственных методов. К их числу относится интересующий нас метод GetConstructors(), возвращающий список параметров, связанных с конструктором. Этот метод действует таким же образом, как и упоминавшийся ранее метод GetParameters(), определенный в классе MethodInfо.
Как только будет обнаружен подходящий конструктор, для создания объекта вызывается метод Invoke(), определенный в классе ConstructorInfo. Ниже приведена одна из форм этого метода.
<b>object Invoke(object[] parameters)</b>
Любые аргументы, которые требуется передать методу, указываются в массиве parameters. Если же аргументы не нужны, то вместо массива parameters указывается пустое значение (null). Но в любом случае количество элементов массива parameters должно совпадать с количеством передаваемых аргументов, а типы аргументов — с типами параметров. Метод Invoke() возвращает ссылку на сконструированный объект.
В приведенном ниже примере программы рефлексия используется для создания экземпляра объекта класса MyClass.
<b>// Создать объект с помощью рефлексии. </b>
<b>using System;</b>
<b>using System.Reflection;</b>
<b>class MyClass {</b>
<b> int x;</b>
<b> int y;</b>
<b> public MyClass(int i) {</b>
<b> Console.WriteLine("Конструирование класса MyClass(int, int). ");</b>
<b> x = y = i;</b>
<b> }</b>
<b> public MyClass(int i, int j) {</b>
<b> Console.WriteLine("Конструирование класса MyClass(int, int). ");</b>
<b> x = i;</b>
<b> y = j;</b>
<b> Show();</b>
<b> }</b>
<b> public int Sum() {</b>
<b> return x + y;</b>
<b> }</b>
<b> public bool IsBetween(int i) {</b>
<b> if ((x < i) && (i < y)) return true;</b>
<b> else return false;</b>
<b> }</b>
<b> public void Set(int a, int b) {</b>
<b> Console.Write("В методе Set (int, int). ");</b>
<b> x = a;</b>
<b> y = b;</b>
<b> Show();</b>
<b> }</b>
<b> // Перегрузить метод Set. </b>
<b> public void Set(double a, double b) {</b>
<b> Console.Write("В методе(double, double). ");</b>
<b> x = (int)a;</b>
<b> y = (int)b;</b>
<b> Show();</b>
<b> }</b>
<b> public void Show() {</b>
<b> Console.WriteLine("Значение x: {0}, значение у: {1}", x, y);</b>
<b> }</b>
<b>}</b>
<b>class InvokeConsDemo {</b>
<b> static void Main() {</b>
<b> Type t = typeof(MyClass);</b>
<b> int val;</b>
<b> // Получить сведения о конструкторе. </b>
<b> ConstructorInfo[] ci = t.GetConstructors();</b>
<b> Console.WriteLine("Доступные конструкторы: ");</b>
<b> foreach (ConstructorInfo с in ci) {</b>