Добавить в цитаты Настройки чтения

Страница 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(&quot;Конструирование класса MyClass(int, int). &quot;);</b>

<b>    x = y = i;</b>

<b>  }</b>

<b>  public MyClass(int i, int j) {</b>

<b>    Console.WriteLine(&quot;Конструирование класса MyClass(int, int). &quot;);</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 &lt; i) &amp;&amp; (i &lt; y)) return true;</b>

<b>    else return false;</b>

<b>  }</b>

<b>  public void Set(int a, int b) {</b>

<b>    Console.Write(&quot;В методе Set (int, int). &quot;);</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(&quot;В методе(double, double). &quot;);</b>

<b>    x = (int)a;</b>

<b>    y = (int)b;</b>

<b>    Show();</b>

<b>  }</b>

<b>  public void Show() {</b>

<b>    Console.WriteLine(&quot;Значение x: {0}, значение у: {1}&quot;, 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(&quot;Доступные конструкторы: &quot;);</b>

<b>    foreach (ConstructorInfo с in ci) {</b>