Язык программирования C#9 и платформа .NET5
public class Motorcycle{[JsonIgnore]public float weightOfCurrentPassengers;// Эти поля остаются сериализируемыми.public bool hasRadioSystem;public bool hasHeadSet;public bool hasSissyBar;}На заметку! Атрибут применяется только к элементу, находящемуся непосредственно после него.
В данный момент пусть вас не беспокоит фактический процесс сериализации объектов (он подробно рассматривается в главе 20). Просто знайте, что для применения атрибута его имя должно быть помещено в квадратные скобки.
Нетрудно догадаться, что к одиночному элементу можно применять множество атрибутов. Предположим, что у вас есть унаследованный тип класса C# (
), который был снабжен атрибутом, чтобы иметь специальное пространство имен XML. Со временем кодовая база изменилась, и класс теперь считается устаревшим для текущей разработки. Вместо того чтобы удалять определение такого класса из кодовой базы (с риском нарушения работы существующего программного обеспечения), его можно пометить атрибутомНоrseAndBuggy. Для применения множества атрибутов к одному элементу просто используйте список с разделителями-запятыми:[Obsolete]using System;using System.Xml.Serialization;namespace ApplyingAttributes{[XmlRoot(Namespace = "http://www.MyCompany.com"),Obsolete("Use another vehicle!")]// Используйте другое транспортное средство!public class HorseAndBuggy{// ...}}В качестве альтернативы применить множество атрибутов к единственному элементу можно также, указывая их друг за другом (конечный результат будет идентичным):
[XmlRoot(Namespace = "http://www.MyCompany.com")][Obsolete("Use another vehicle!")]public class HorseAndBuggy{// ...}Сокращенная система обозначения атрибутов C#
Заглянув в документацию по .NET Core, вы можете заметить, что действительным именем класса, представляющего атрибут
, является[Obsolete], а не простоObsoleteAttribute. По соглашению имена всех атрибутов .NET Core (включая специальные атрибуты, которые создаете вы сами) снабжаются суффиксомObsolete. Тем не менее, чтобы упростить процесс применения атрибутов, в языке C# не требуется обязательный ввод суффиксаAttribute. Учитывая это, показанная ниже версия типаAttributeидентична предыдущей версии (но влечет за собой более объемный клавиатурный набор):HorseAndBuggy[SerializableAttribute][ObsoleteAttribute("Use another vehicle!")]public class HorseAndBuggy{// ...}Имейте в виду, что такая сокращенная система обозначения для атрибутов предлагается только в С#. Ее поддерживают не все языки .NET Core.
Указание параметров конструктора для атрибутов
Обратите внимание, что атрибут
может принимать то, что выглядит как параметр конструктора. Если вы просмотрите формальное определение атрибута[Obsolete], щелкнув на нем правой кнопкой мыши в окне кода и выбрав в контекстном меню пункт Go То Definition (Перейти к определению), то обнаружите, что данный класс на самом деле предоставляет конструктор, принимающий[Obsolete]:System.Stringpublic sealed class ObsoleteAttribute : Attribute{public ObsoleteAttribute(string message, bool error);public ObsoleteAttribute(string message);public ObsoleteAttribute();public bool IsError { get; }public string? Message { get; }}Важно понимать, что когда вы снабжаете атрибут параметрами конструктора, этот атрибут не размещается в памяти до тех пор, пока к параметрам не будет применена рефлексия со стороны другого типа или внешнего инструмента. Строковые данные, определенные на уровне атрибутов, просто сохраняются внутри сборки в виде блока метаданных.
Атрибут [Obsolete] в действии
Теперь, поскольку класс
помечен как устаревший, следующая попытка выделения памяти под его экземпляр:HorseAndBuggyusing System;using ApplyingAttributes;Console.WriteLine("Hello World!");HorseAndBuggy mule = new HorseAndBuggy();приводит к выдаче компилятором предупреждающего сообщения, а именно — предупреждения CS0618 с сообщением, включающим информацию, которая передавалась атрибуту:
‘HorseAndBuggy’ is obsolete: ‘Use another vehicle!'HorseAndBuggy устарел: Используйте другое транспортное средство!Среды Visual Studio и Visual Studio Code оказывают помощь также посредством IntelliSense, получая информацию через рефлексию.
На рис. 17.1 показаны результаты действия атрибута
в Visual Studio, а на рис. 17.2 — в Visual Studio Code. Обратите внимание, что в обеих средах используется термин deprecated вместо obsolete.[Obsolete]