Kniga-Online.club
» » » » Герберт Шилдт - C# 4.0: полное руководство

Герберт Шилдт - C# 4.0: полное руководство

Читать бесплатно Герберт Шилдт - C# 4.0: полное руководство. Жанр: Программирование издательство -, год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

Рассмотрим следующий пример, демонстрирующий полностью автоматизированное обнаружение типов. В этом примере сначала загружается сборка MyClasses.ехе, затем конструируется объект класса MyClass и далее вызываются все методы, объявленные в классе MyClass, причем о них ничего заранее неизвестно.

// Использовать класс MyClass, ничего не зная о нем заранее.

using System;

using System.Reflection;

class ReflectAssemblyDemo {

  static void Main() {

    int val;

    Assembly asm = Assembly.LoadFrom("MyClasses.exe");

    Type[] alltypes = asm.GetTypes();

    Type t = alltypes[0]; // использовать первый обнаруженный класс

    Console.WriteLine("Использовано: " + t.Name);

    ConstructorInfo[] ci = t.GetConstructors();

    // Использовать первый обнаруженный конструктор.

    ParameterInfo[] cpi = ci[0].GetParameters();

    object reflectOb;

    if (cpi.Length > 0) {

      object[] consargs = new object[cpi.Length];

      // Инициализировать аргументы,

      for (int n = 0; n < cpi.Length; n++) consargs[n] = 10 + n * 20;

      // Сконструировать объект.

      reflectOb = ci[0].Invoke(consargs);

    }

    else

      reflectOb = ci[0].Invoke(null);

    Console.WriteLine("nВызов методов для объекта reflectOb.");

    Console.WriteLine();

    // Игнорировать наследуемые методы.

    MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly |

                  BindingFlags.Instance | BindingFlags.Public);

    // Вызвать каждый метод,

    foreach (MethodInfo m in mi) {

      Console.WriteLine("Вызов метода {0} ", m.Name);

      // Получить параметры.

      ParameterInfo[] pi = m.GetParameters();

      // Выполнить методы,

      switch (pi.Length) {

        case 0: // аргументы отсутствуют

          if (m.ReturnType == typeof(int)) {

            val = (int)m.Invoke(reflectOb, null);

            Console.WriteLine("Результат: " + val);

          }

          else if (m.ReturnType == typeof(void)) {

            m.Invoke(reflectOb, null);

          }

          break;

        case 1: // один аргумент

          if (pi[0].ParameterType == typeof(int)) {

            object[] args = new object[1];

            args[0] = 14;

            if ((bool)m.Invoke(reflectOb, args))

              Console.WriteLine("Значение 14 находится между x и у");

            else

              Console.WriteLine("Значение 14 не находится между х и у");

          }

          break;

        case 2: // два аргумента

          if ((pi[0].ParameterType == typeof(int)) &&

                    (pi[1].ParameterType == typeof(int))) {

            object[] args = new object[2];

            args[0] = 9;

            args[1] = 18;

            m.Invoke(reflectOb, args);

          }

          else if ((pi[0].ParameterType == typeof(double)) &&

                    (pi[1].ParameterType == typeof(double))) {

            object[] args = new object[2];

            args[0] = 1.12;

            args[1] = 23.4;

            m.Invoke(reflectOb, args);

          }

          break;

      }

      Console.WriteLine();

    }

  }

}

Эта программа дает следующий результат.

Использовано: MyClass

Конструирование класса MyClass(int).

Значение х: 10, значение у: 10

Вызов методов для объекта reflectOb.

Вызов метода Sum

Результат: 20

Вызов метода IsBetween

Значение 14 не находится между х и у

Вызов метода Set

В методе Set (int, int). Значение х: 9, значение у: 18

Вызов метода Set

В методе Set(double, double). Значение х: 1, значение у: 23

Вызов метода Show

Значение х: 1, значение у: 23

Эта программа работает довольно просто, но все же требует некоторых пояснений. Во-первых, получаются и используются только те методы, которые явно объявлены в классе MyClass. Для этой цели служит форма BindingFlags метода GetMethods(), чтобы воспрепятствовать вызову методов, наследуемых от объекта. И во-вторых, количество параметров и возвращаемый тип каждого метода получаются динамически, а затем определяются и проверяются в операторе switch. На основании этой информации формируется вызов каждого метода.

Атрибуты

В C# разрешается вводить в программу информацию декларативного характера в форме атрибута, с помощью которого определяются дополнительные сведения (метаданные), связанные с классом, структурой, методом и т.д. Например, в программе можно указать атрибут, определяющий тип кнопки, которую должен отображать конкретный класс. Атрибуты указываются в квадратных скобках перед тем элементом, к которому они применяются. Следовательно, атрибут не является членом класса, но обозначает дополнительную информацию, присоединяемую к элементу.

Основы применения атрибутов

Атрибут поддерживается классом, наследующим от класса System.Attribute. Поэтому классы атрибутов должны быть подклассами класса Attribute. В классе Attribute определены основные функциональные возможности, но далеко не все они нужны для работы с атрибутами. В именах классов атрибутов принято употреблять суффикс Attribute. Например, ErrorAttribute — это имя класса атрибута, описывающего ошибку.

При объявлении класса атрибута перед его именем указывается атрибут AttributeUsage. Этот встроенный атрибут обозначает типы элементов, к которым может применяться объявляемый атрибут. Так, применение атрибута может ограничиваться одними методами.

Создание атрибута

В классе атрибута определяются члены, поддерживающие атрибут. Классы атрибутов зачастую оказываются довольно простыми и содержат небольшое количество полей или свойств. Например, атрибут может определять примечание, описывающее элемент, к которому присоединяется атрибут. Такой атрибут может принимать следующий вид.

  [AttributeUsage(AttributeTargets.All) ]

public class RemarkAttribute : Attribute {

  string pri_remark; // базовое поле свойства Remark

  public RemarkAttribute(string comment) {

    pri_remark = comment;

  }

  public string Remark {

    get {

      return pri_remark;

    }

  }

}

Проанализируем этот класс атрибута построчно.

Объявляемый атрибут получает имя RemarkAttribute. Его объявлению предшествует встроенный атрибут AttributeUsage, указывающий на то, что атрибут RemarkAttribute может применяться ко всем типам элементов. С помощью встроенного атрибута AttributeUsage можно сузить перечень элементов, к которым может присоединяться объявляемый атрибут. Подробнее о его возможностях речь пойдет далее в этой главе.

Далее объявляется класс RemarkAttribute, наследующий от класса Attribute. В классе RemarkAttribute определяется единственное закрытое поле pri_remark, поддерживающее одно открытое и доступное для чтения свойство Remark. Это свойство содержит описание, связываемое с атрибутом. (Конечно, Remark можно было бы объявить как автоматически реализуемое свойство с закрытым аксессором set, но ради наглядности данного примера выбрано свойство, доступное только для чтения.) В данном классе определен также один открытый конструктор, принимающий строковый аргумент и присваивающий его свойству Remark. Этим пока что ограничиваются функциональные возможности класса RemarkAttribute, готового к применению.

Перейти на страницу:

Герберт Шилдт читать все книги автора по порядку

Герберт Шилдт - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


C# 4.0: полное руководство отзывы

Отзывы читателей о книге C# 4.0: полное руководство, автор: Герберт Шилдт. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*