Согласно спецификации языка C # ,
По соглашению, классы атрибутов именуются с суффиксом Attribute
. имя-атрибута в форме имя-типа может включать или не включать этот суффикс.
Это ярлык, предоставляемый компилятором C # и никоим образом не являющийся функцией CLR. Другим примером специальной обработки атрибутов компилятором является атрибут ObsoleteAttribute : этот параметр заставляет компилятор выдавать предупреждение / ошибку, но он не имеет специального значения для CLR.
Что касается разрешения атрибутов, см. Ссылку выше. Подводя итог:
Если класс атрибута найден как с этим суффиксом, так и без него, возникает неоднозначность и возникает ошибка времени компиляции. Если attribute-name
написано так, что его самый правый идентификатор является дословным идентификатором , то сопоставляется только атрибут без суффикса, что позволяет разрешить такую неоднозначность.
«Идентификатор дословно» - это идентификатор с префиксом @
.
Продолжаем с MSDN:
using System;
[AttributeUsage(AttributeTargets.All)]
public class X: Attribute
{}
[AttributeUsage(AttributeTargets.All)]
public class XAttribute: Attribute
{}
[X] // Error: ambiguity
class Class1 {}
[XAttribute] // Refers to XAttribute
class Class2 {}
[@X] // Refers to X
class Class3 {}
[@XAttribute] // Refers to XAttribute
class Class4 {}
Атрибут [X]
является неоднозначным, поскольку он может относиться либо к X
, либо к XAttribute
. Использование стенографического идентификатора позволяет указать точное намерение в таких редких случаях. Атрибут [XAttribute]
не является неоднозначным (хотя это было бы, если бы существовал класс атрибута с именем XAttributeAttribute
!). Если объявление для класса X
удалено, то оба атрибута ссылаются на класс атрибута с именем XAttribute
следующим образом:
using System;
[AttributeUsage(AttributeTargets.All)]
public class XAttribute: Attribute
{}
[X] // Refers to XAttribute
class Class1 {}
[XAttribute] // Refers to XAttribute
class Class2 {}
[@X] // Error: no attribute named "X"
class Class3 {}