А сейчас снова взгляните на атрибут
AttributeUsage
из предыдущего раздела. Заметьте: параметр
validon
является позиционным и, естественно, обязательным. Он позволяет задавать типы, к которым может быть прикреплен атрибут. На самом деле тип параметра
validon
атрибута
Attribute-Usage — AttributeTargets,
представляющий собой перечисление, определяемое так:
public enum AttributeTargets <
Assembly = 0x0001,
Module = 0x0002,
Class = 0x0004,
Struct = 0x0008,
Enum = 0x0010,
Constructor = 0x0020,
Method = 0x0040,
Property = 0x0080,
Field = 0x0100,
Event = 0x0200,
Interface = 0x0400,
Parameter = 0x0800,
Delegate = 0x1000,
All = Assembly | Module | Class | Struct | Enum | Constructor | Method | Property | Field | Event | Interface | Parameter | Delegate,
ClassMembers = Class | Struct | Enum | Constructor | Method | Property | Field | Event | Delegate | Interface, }
При использовании атрибута
Attribute Usage
можно задать
Attribute-Targets.All.
Это позволяет прикрепить атрибут к любому из типов в списке перечисления
AttributeTargets.
Если вы вообще не определили
Attribute-Usage,
можете прикрепить атрибут к любому типу — это значение по умолчанию. И тут вы можете спросить: "А зачем вообще значение
vali-don?"
А затем, что с вашим атрибутом могут применяться именованные параметры, которые вы, может быть, захотите изменить. Помните: используя именованный параметр, вы должны поставить все позиционные параметры перед ним. Это позволяет легко задавать применение атрибутов по умолчанию, определяемое
AttriubuteTargets.All,
и при этом устанавливать именованные параметры.
Итак, когда и для чего задавать параметр
validon (AttributeTargets)!
Когда вам нужно точно контролировать способы применения атрибута. В наших примерах мы создали атрибут
RemoteObjeci'Attribute,
применимый только к классам, атрибут
TransactionableAttribute,
применимый только к методам, и атрибут
Registry Key Attribute,
который имеет смысл лишь по отношению к полям. Если мы хотим убедиться, что они были использованы для аннотации только тех типов, для которых они разработаны, мы можем определить их так (для ясности тела атрибутов не приводятся):
[Att ributeUsage(Att ributeTa rgets.Class)] public class RemoteObjectAttribute : Attribute] {
}
[Att rlbuteUsage(AttributeTargets.Method)]
public class TransactionableAttribute : Attribute
{
}
[Att ributeUsage(Att ributeTargets.Field)]
public class RegistryKeyAttribute : Attribute
<
}
И последний момент относительно перечисления
AttributeTargets:
вы можете комбинировать члены с помощью оператора |. Если у вас есть атрибут, применимый и к полям, и к свойствам,
Attribute Usage
можно прикрепить так:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]