Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Троелсен Э. Язык программирования С# 2010 и п...docx
Скачиваний:
113
Добавлен:
21.09.2019
Размер:
6.92 Mб
Скачать

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

Как уже упоминалось в этой главе, атрибуты будут бесполезны до тех пор, пока некоторый фрагмент программного обеспечения не выполнит их отображение. После выявления атрибута соответствующий фрагмент программного обеспечения может выбрать подходящее действие. Как и само приложение, этот "фрагмент программного обеспечения" может для выявления пользовательского атрибута использовать статическое или динамическое связывание. Для статического связывания требуется, чтобы приложение-клиент к моменту компиляции уже имели определение соответствующего атрибута (в нашем случае это атрибут VehicleDescriptionAttribute). Компоновочный блок AttributedCarLibrary определяет пользовательский атрибут, как открытый класс, поэтому статическое связывание в данном случае будет наилучшим выбором.

Для иллюстрации процесса отображения пользовательских атрибутов создайте новое консольное приложение C# с именем VehicleDescriptionAttributeReader. Затем установите в нем ссылку на компоновочный блок AttributedCarLibrary. Наконец, поместите в исходный файл *.cs следующий программный код.

// Отображение пользовательских атрибутов при статическом связывании.

using System;

using AttributedCarLibrary;

public class Program {

 static void Main(string [] args) {

  // Получение Type для представления Winnebago.

  Type t = typeof(Winnebago);

  // Получение атрибутов Winnebago.

  object[] customAtts = t.GetCustomAttributes(false);

  // Печать описания.

  Console.WriteLine("*** Значение VehicleDescriptionAttribute ***\n");

  foreach(VehicleDescriptionAtttibute v in customAtts) Console.WriteLine("-› {0}\n", v.Description);

  Console.ReadLine();

 }

}

Как следует из самого названия, метод Type.GetCustomAttributes() возвращает массив объектов, представляющих все атрибуты, примененные тому к члену, который представлен с помощью Туре (логический параметр этого метода указывает, следует ли расширить поиск на всю цепочку наследования). После получения списка атрибутов выполняется цикл по всем классам VehicleDescriptionAttribute с выводом на печать значения, полученного свойством Description.

Исходный код. Проект VehicleDescriptionAttributeReader размещен в подкаталоге, соответствующем главе 12.

Отображение атрибутов при динамическом связывании

В предыдущем примере использовалось статическое связывание и печатались данные описания для типа Winnebago. Это было возможно благодаря тому, что тип класса VehicleDescriptionAttribute был определен, как открытый член компоновочного блока AttributedCarLibrary. Но для отображения атрибутов можно также использовать динамическую загрузку и динамическое связывание.

Создайте новый консольный проект (VehicleDescriptionAttributeReaderLateBinding) и скопируйте AttributedCarLibrary.dll в каталог \Bin\Debug этого проекта. Затем обновите метод Main() так, как предлагается ниже.

using System.Reflection;

 namespace VehicleDescriptionAttributeReaderLateBinding {

  class Program {

   static void Main(string[] args) {

    Console.WriteLine("*** Описания транспортных средств ***\n");

    // Загрузка локальной копии AttributedCarLibrагу.

    Assembly asm = Assembly.Load(AttributedCarLibrary");

    // Получение информации типа для VehicleDescriptionAttribute.

    Type vehicleDesc = asm.GetType("AttributedCarLibrary.VehicleDescriptionAttribute");

    // Получение информации типа для свойства Description.

    PropertyInfо propDesc = vehicleDesc.GetProperty("Description");

    // Получение всех типов данного компоновочного блока.

    Туре[] types = asm.GetTypes();

    // Получение VehicleDescriptionAttribute для каждого типа.

    foreach (Type t in types) {

     object[] objs = t.GetCustomAttributes(vehicleDesc, false);

     // Итерации по VehicleDescriptionAttribute и печать

     // описаний с динамическим связыванием.

     foreach(object о in objs) {

      Console.WriteLine("-› {0}: {1}\n", t.Name, propDesc.GetValue(o, null));

     }

    }

    Console.ReadLine();

   }

  }

}

Если вы внимательно анализировали все примеры этой главы, то листинг этого метода Main() должен быть для вас (более или менее) понятным. Единственным заслуживающим внимания моментом здесь является использование метода PropertyInfo.GetValue() для доступа к свойству. На рис. 12.10 показан соответствующий вывод.

Рис. 12.10. Отображение атрибутов при динамическом связывании

Исходный код. Проект VehiсleDescriptionAttributeReaderLateBinding размещен в подкаталоге, соответствующем главе 12.