According to the C# Language Specification,
By convention, attribute classes are named with a suffix of Attribute
. An attribute-name of the form type-name may either include or omit this suffix.
This is a shortcut provided by the C# compiler and by no means a CLR feature. Another example of special treatment of attributes by the compiler is an ObsoleteAttribute attribute: this one forces a compiler to issue a warning/error, but it has no special meaning for the CLR.
As for how attributes are resolved, see the link above. To sum it up:
If an attribute class is found both with and without this suffix, an ambiguity is present, and a compile-time error results. If the attribute-name
is spelled such that its right-most identifier is a verbatim identifier, then only an attribute without a suffix is matched, thus enabling such an ambiguity to be resolved.
A "verbatim identifier" is an identifier with an @
prefix.
Continuing with 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 {}
The attribute [X]
is ambiguous, since it could refer to either X
or XAttribute
. Using a verbatim identifier allows the exact intent to be specified in such rare cases. The attribute [XAttribute]
is not ambiguous (although it would be if there was an attribute class named XAttributeAttribute
!). If the declaration for class X
is removed, then both attributes refer to the attribute class named XAttribute
, as follows:
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 {}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…