public class HorseAndBuggy
{
}
}
// Winnebago.cs
namespace AttributedCarLibrary
{
[VehicleDescription("A very long, slow, but feature-rich auto")]
// Очень длинный, медленный, но обладающий высокими
// техническими характеристиками автомобиль
public class Winnebago
{
}
}
Синтаксис именованных свойств
Обратите внимание, что классу Motorcycle
[VehicleDescription] лежащие в основе строковые данные устанавливаются с применением свойства Description. Когда внешний агент выполнит рефлексию для этого атрибута, свойству Description будет передано указанное значение (синтаксис именованных свойств разрешен, только если атрибут предоставляет поддерживающее запись свойство .NET Core).По контрасту для типов HorseAndBuggy
Winnebago синтаксис именованных свойств не используется, а строковые данные просто передаются через специальный конструктор. В любом случае после компиляции сборки AttributedCarLibrary с помощью утилиты ildasm.exe можно просмотреть добавленные описания метаданных. Например, ниже показано встроенное описание класса Winnebago:// CustomAttribute #1
// -------------------------------------------------------
// CustomAttribute Type: 06000005
// CustomAttributeName: AttributedCarLibrary.VehicleDescriptionAttribute :: instance void
.ctor(class System.String)// Length: 45
// Value : 01 00 28 41 20 76 65 72 79 20 6c 6f 6e 67 2c 20 > (A very long, <
// : 73 6c 6f 77 2c 20 62 75 74 20 66 65 61 74 75 72 >slow, but feature<
// : 65 2d 72 69 63 68 20 61 75 74 6f 00 00 >e-rich auto <
// ctor args: ("A very long, slow, but feature-rich auto")
Ограничение использования атрибутов
По умолчанию специальные атрибуты могут быть применены практически к любому аспекту кода (методам, классам, свойствам и т.д.). Таким образом, если бы это имело смысл, то VehicleDescription
[VehicleDescription("A very long, slow, but feature-rich auto")]
public class Winnebago
{
[VehicleDescription("My rocking CD player")]
public void PlayMusic(bool On)
{
...
}
}
В одних случаях такое поведение является точно таким, какое требуется, но в других может возникнуть желание создать специальный атрибут, применяемый только к избранным элементам кода. Чтобы ограничить область действия специального атрибута, понадобится добавить к его определению атрибут [AttributeUsage]
AttributeTargets:// Это перечисление определяет возможные целевые элементы для атрибута.
public enum AttributeTargets
{
All, Assembly, Class, Constructor,
Delegate, Enum, Event, Field, GenericParameter,
Interface, Method, Module, Parameter,
Property, ReturnValue, Struct
}
Кроме того, атрибут [AttributeUsage]
AllowMultiple), которое указывает, может ли атрибут применяться к тому же самому элементу более одного раза (стандартным значением является false). Вдобавок [AttributeUsage] разрешает указывать, должен ли атрибут наследоваться производными классами, с использованием именованного свойства Inherited (со стандартным значением true).