Язык программирования C#9 и платформа .NET5
На заметку! На момент написания главы в хранилище GitHub для MSBuild шло активное обсуждение относительно добавления возможности поддержки нестроковых параметров, что позволило бы добавлять атрибут
с использованием файла проекта вместо файлаCLSCompliant.*.csУстановите несколько свойств (таких как
,Authors), щелкнув правой кнопкой мыши на имени проекта в окне Solution Explorer, выберите в контекстном меню пункт Properties (Свойства) и в открывшемся окне свойств перейдите на вкладку Package. Кроме того, добавьтеDescription, как делалось в главе 16. Содержимое вашего файла проекта должно выглядеть примерно так, как представленное ниже:InternalsVisibleToAttribute<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.csusing 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 asample car library withattributes")][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. Выполните приведенные далее команды CLI (каждая должна вводиться по отдельности):AttributedCarLibrarydotnet new console -lang c# -n VehicleDescriptionAttributeReader -o .\VehicleDescriptionAttributeReader -f net5.0dotnet sln .\Chapter17_AllProjects.sln add .\VehicleDescriptionAttributeReaderdotnet add VehicleDescriptionAttributeReader reference .\AttributedCarLibraryПоместите в файл
следующий код:Program.сsusing 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);