Ограничение использования атрибута
Ограничение использования атрибута
По умолчанию пользовательские атрибуты могут применяться к любой части программного кода (к методам, классам, свойствам и т.д.). Поэтому, если только это имеет смысл, можно использовать VehicleDescription для определения (среди прочего) методов, свойств или полей.
[VehicleDescription("Большое, тяжелое, но высокотехнологичное авто")]
public class Winnebago {
[VehicleDescription("Мой мощный CD-плейер")]
public void PlayMusic(bool On) {
…
}
}
В некоторых случаях это оказывается именно тем, что нужно. Но в других случаях бывает нужно создать пользовательский атрибут, который должен применяться только к определенным элементам программного кода. Если вы хотите ограничить контекст применения пользовательского атрибута, то при определении пользовательского атрибута нужна применить атрибут [AttributeUsage]. Атрибут [AttributeUsage] позволяет указать любую комбинацию значений (связанных операцией OR) из перечня AttributeTargets.
// Этот перечень задает возможные целевые значения для атрибута.
public enum AttributeTargets {
All, Assembly, Class, Constructor,
Delegate, Enum, Event, Field,
Interface, Method, Module, Parameter,
Property, ReturnValue, Struct
}
Кроме того, [AttributeUsage] позволяет опционально установить именованное свойство (AllowMultiple), которое указывает, может ли атрибут примениться к одному и тому же элементу многократно. Точно так же с помощью именованного свойства Inherited атрибут [AttributeUsage] позволяет указать, должен ли создаваемый атрибут наследоваться производными классами.
Чтобы атрибут [VehicleDescription] мог применяться к классу или структуре только один раз (и соответствующее значение не наследовалось производными типами), можно изменить определение VehicleDescriptionAttribute так.
// На этот раз для аннотации нашего пользовательского атрибута
// мы используем атрибут AttributeUsage.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
public class VehicleDescriptionAttribute: System.Attribute {
…
}
Теперь если разработчик попытается применить атрибут [VehicleDescription] к чему-либо, кроме класса или структуры, будет сгенерировано сообщение об ошибке компиляции.
Совет. Вашей привычкой должно стать явное указание флагов применения для любого создаваемого вами пользовательского атрибута, поскольку не все языки программирования .NET приветствуют использование атрибутов, не имеющих квалификационных указаний!