Принципы объектно-ориентированного программирования

         

Определение целевого типа атрибута



Определение целевого типа атрибута

А сейчас снова взгляните на атрибут 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)]



Содержание раздела