public class Motorcycle
{
[JsonIgnore]
public float weightOfCurrentPassengers;
// Эти поля остаются сериализируемыми.
public bool hasRadioSystem;
public bool hasHeadSet;
public bool hasSissyBar;
}
На заметку! Атрибут применяется только к элементу, находящемуся непосредственно после него.
В данный момент пусть вас не беспокоит фактический процесс сериализации объектов (он подробно рассматривается в главе 20). Просто знайте, что для применения атрибута его имя должно быть помещено в квадратные скобки.
Нетрудно догадаться, что к одиночному элементу можно применять множество атрибутов. Предположим, что у вас есть унаследованный тип класса C# (
НоrseAndBuggy
), который был снабжен атрибутом, чтобы иметь специальное пространство имен XML. Со временем кодовая база изменилась, и класс теперь считается устаревшим для текущей разработки. Вместо того чтобы удалять определение такого класса из кодовой базы (с риском нарушения работы существующего программного обеспечения), его можно пометить атрибутом
[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
, а не просто
Obsolete
. По соглашению имена всех атрибутов .NET Core (включая специальные атрибуты, которые создаете вы сами) снабжаются суффиксом
Attribute
. Тем не менее, чтобы упростить процесс применения атрибутов, в языке C# не требуется обязательный ввод суффикса
Attribute
. Учитывая это, показанная ниже версия типа
HorseAndBuggy
идентична предыдущей версии (но влечет за собой более объемный клавиатурный набор):
[SerializableAttribute]
[ObsoleteAttribute("Use another vehicle!")]
public class HorseAndBuggy
{
// ...
}
Имейте в виду, что такая сокращенная система обозначения для атрибутов предлагается только в С#. Ее поддерживают не все языки .NET Core.
Указание параметров конструктора для атрибутов
Обратите внимание, что атрибут
[Obsolete]
может принимать то, что выглядит как параметр конструктора. Если вы просмотрите формальное определение атрибута
[Obsolete]
, щелкнув на нем правой кнопкой мыши в окне кода и выбрав в контекстном меню пункт
Go То Definition (Перейти к определению), то обнаружите, что данный класс на самом деле предоставляет конструктор, принимающий
System.String
:
public 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] в действии
Теперь, поскольку класс
HorseAndBuggy
помечен как устаревший, следующая попытка выделения памяти под его экземпляр:
using 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 показаны результаты действия атрибута
[Obsolete]
в Visual Studio, а на рис. 17.2 — в Visual Studio Code. Обратите внимание, что в обеих средах используется термин
deprecated вместо
obsolete.