Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>

<TargetFramework>net5.0</TargetFramework>

<Authors>Philip Japikse</Authors>

<Company>Apress</Company>

<Description>This is a simple car library with attributes</Description>

</PropertyGroup>

<ItemGroup>

<AssemblyAttribute Include="System.Runtime.CompilerServices.

InternalsVisibleToAttribute">

<_Parameter1>CSharpCarClient</_Parameter1>

</AssemblyAttribute>

</ItemGroup>

</Project>

После

компиляции своего проекта перейдите в каталог \
obj\Debug\net5.0
и отыщите файл
AttributedCarLibrary.AssemblyInfo.cs
. Открыв его, вы увидите установленные свойства в виде атрибутов (к сожалению, они не особо читабельны в таком формате):

using System;

using System.Reflection;

[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute

("CSharpCarClient")]

[assembly: System.Reflection.AssemblyCompanyAttribute("Philip Japikse")]

[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]

[assembly: System.Reflection.AssemblyDescriptionAttribute("This is a

sample car library with
attributes")]

[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]

[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]

[assembly: System.Reflection.AssemblyProductAttribute("AttributedCarLibrary")]

[assembly: System.Reflection.AssemblyTitleAttribute("AttributedCarLibrary")]

[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

И последнее замечание, касающееся атрибутов сборки: вы можете отключить генерацию файла

AssemblyInfо.cs
, если хотите управлять процессом самостоятельно.

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

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

VehicleDescriptionAttribute
) должно находиться в клиентском приложении на этапе компиляции. Учитывая то, что специальный атрибут определен в сборке
AttributedCarLibrary
как открытый класс, раннее связывание будет наилучшим выбором.

Чтобы проиллюстрировать процесс рефлексии специальных атрибутов, вставьте в решение новый проект консольного приложения по имени

VehicleDescriptionAttributeReader
. Добавьте в него ссылку на проект
AttributedCarLibrary
. Выполните приведенные далее команды CLI (каждая должна вводиться по отдельности):

dotnet new console -lang c# -n VehicleDescriptionAttributeReader -o .\

VehicleDescriptionAttributeReader -f net5.0

dotnet sln .\Chapter17_AllProjects.sln add .\VehicleDescriptionAttributeReader

dotnet add VehicleDescriptionAttributeReader reference .\AttributedCarLibrary

Поместите

в файл
Program.сs
следующий код:

using System;

using AttributedCarLibrary;

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

ReflectOnAttributesUsingEarlyBinding;

Console.ReadLine;

static void ReflectOnAttributesUsingEarlyBinding

{

// Получить объект Type, представляющий тип Winnebago.

Type t = typeof(Winnebago);

// Получить все атрибуты Winnebago.

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

// Вывести описание.

foreach (VehicleDescriptionAttribute v in customAtts)

{

Console.WriteLine("-> {0}\n", v.Description);

}

}

Метод

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

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

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

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

Добавьте к решению новый проект консольного приложения по имени

VehicleDescriptionAttributeReaderLateBinding
, установите его в качестве стартового и скопируйте сборку
AttributedCarLibrary.dll
в каталог проекта (или в
\bin\Debug\net5.0
, если вы работаете в Visual Studio). Модифицируйте файл
Program.cs
, как показано ниже:

using System;

using System.Reflection;

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

ReflectAttributesUsingLateBinding;

Console.ReadLine;

static void ReflectAttributesUsingLateBinding

{

try

{

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

Поделиться с друзьями: