Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 328 329 330 331 332 333 334 335 336 ... 642

  }

}

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

Рефлексия атрибутов с использованием позднего связывания

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

Добавьте к решению новый проект консольного приложения по имени VehicleDescriptionAttributeReaderLateBinding, установите его в качестве стартового и скопируйте сборку AttributedCarLibrary.dll в каталог проекта (или в binDebugnet5.0, если вы работаете в Visual Studio). Модифицируйте файл Program.cs, как показано ниже:

using System;

using System.Reflection;

Console.WriteLine("***** Value of VehicleDescriptionAttribute *****n");

ReflectAttributesUsingLateBinding();

Console.ReadLine();

static void ReflectAttributesUsingLateBinding()

{

  try

  {

<b>    // Загрузить локальную копию сборки AttributedCarLibrary.</b>

    Assembly asm = Assembly.LoadFrom(&quot;AttributedCarLibrary&quot;);

<b>    // Получить информацию о типе VehicleDescriptionAttribute.</b>

    Type vehicleDesc =

      asm.GetType(&quot;AttributedCarLibrary.VehicleDescriptionAttribute&quot;);

<b>     // Получить информацию о типе свойства Description.</b>

     PropertyInfo propDesc = vehicleDesc.GetProperty(&quot;Description&quot;);

<b>     // Получить все типы в сборке.</b>

     Type[] types = asm.GetTypes();

<b>    // Пройти по всем типам и получить любые атрибуты VehicleDescriptionAttribute.</b>

    foreach (Type t in types)

    {

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

<b>      // Пройти по каждому VehicleDescriptionAttribute и вывести</b>

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

<b>      // описание, используя позднее связывание.</b>

      foreach (object o in objs)

      {

        Console.WriteLine(&quot;-&gt; {0}: {1}n&quot;, t.Name,

          propDesc.GetValue(o, null));

      }

    }

  }

  catch (Exception ex)

  {

    Console.WriteLine(ex.Message);

  }

}

Если вы прорабатывали примеры, рассмотренные ранее в главе, тогда приведенный код должен быть более или менее понятен. Единственный интересный момент здесь связан с применением метода PropertyInfo.GetValue(), который служит для активизации средства доступа к свойству. Вот как выглядит вывод, полученный в результате выполнения текущего примера:

***** Value of VehicleDescriptionAttribute *****

-&gt; Motorcycle: My rocking Harley

-&gt; HorseAndBuggy: The old gray mare, she ain't what she used to be...

-&gt; Winnebago: A very long, slow, but feature-rich auto

Практическое использование рефлексии позднего связывания и специальных атрибутов

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

Что понимается под расширяемостью? Возьмем IDE -среду Visual Studio. Когда это приложение разрабатывалось, в его кодовую базу были вставлены многочисленные "привязки", чтобы позволить другим производителям программного обеспечения подключать специальные модули к IDE - среде. Очевидно, что у разработчиков Visual Studio отсутствовал какой-либо способ установки ссылок на внешние сборки .NET Core, которые на тот момент еще не были созданы (и потому раннее связывание недоступно), тогда как они обеспечили наличие в приложении необходимых привязок? Ниже представлен один из возможных способов решения задачи.

1. Во-первых, расширяемое приложение должно предоставлять некоторый механизм ввода, позволяющий пользователю указать модуль для подключения (наподобие диалогового окна или флага командной строки). Это требует динамической загрузки.

2. Во-вторых, расширяемое приложение должно иметь возможность выяснять, поддерживает ли модуль корректную функциональность (такую как набор обязательных интерфейсов), необходимую для его подключения к среде. Это требует рефлексии.

1 ... 328 329 330 331 332 333 334 335 336 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий