Ответ 1
В соответствии с С# Language Specification,
По соглашению классы атрибутов называются суффиксом
Attribute
. Имя атрибута типа type-name может включать или исключать этот суффикс.
Это ярлык, предоставляемый компилятором С# и никоим образом не CLR-функцией. Другим примером специальной обработки атрибутов компилятором является атрибут ObsoleteAttribute: это заставляет компилятор выдавать предупреждение/ошибку, но это не имеет особого значения для CLR.
Что касается определения атрибутов, см. ссылку выше. Подводя итог:
Если класс атрибута найден как с суффиксом, так и без него, возникает неоднозначность и возникает ошибка времени компиляции. Если символ
attribute-name
записан таким образом, что его самый правый идентификатор является verbatim identifier, то сопоставляется только атрибут без суффикса, что позволяет такая неопределенность должна быть решена.
A "verbatim identifier" - это идентификатор с префиксом @
.
Продолжение работы с 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 {}