
24 Attributes
24.2 Attribute specification
Paragraph 11 Attribute specification is the application of a previously defined attribute to a declaration. 2 An attribute is a piece of additional declarative information that is specified for a declaration. 3 Attributes can be specified at global scope (to specify attributes on the containing assembly) and for type-declarations (§16.5), class-member-declarations (§17.2), interface-member-declarations (§20.2), enum-member-declarations (§21.1), accessor-declarations (§17.6.2), event-accessor-declarations (§17.7), and formal-parameter-lists (§17.5.1).
Paragraph 21 Attributes are specified in attribute sections. 2 An attribute section consists of a pair of square brackets, which surround a comma-separated list of one or more attributes. 3 The order in which attributes are specified in such a list, and the order in which sections attached to the same program entity are arranged, is not significant. 4 For instance, the attribute specifications [A][B], [B][A], [A, B], and [B, A] are equivalent. global-attributes : global-attribute-sections global-attribute-sections : global-attribute-section global-attribute-sections global-attribute-section global-attribute-section : [ global-attribute-target-specifier attribute-list ] [ global-attribute-target-specifier attribute-list ,] global-attribute-target-specifier : global-attribute-target : global-attribute-target : assembly attributes : attribute-sections attribute-sections : attribute-section attribute-sections attribute-section attribute-section : [ attribute-target-specifieropt attribute-list ] [ attribute-target-specifieropt attribute-list ,] attribute-target-specifier : attribute-target : attribute-target : field event method param property return type attribute-list : attribute attribute-list , attribute attribute : attribute-name attribute-argumentsopt attribute-name : type-name attribute-arguments : ( positional-argument-listopt ) ( positional-argument-list , named-argument-list ) ( named-argument-list ) positional-argument-list : positional-argument positional-argument-list , positional-argument positional-argument : attribute-argument-expression named-argument-list : named-argument named-argument-list , named-argument named-argument : identifier = attribute-argument-expression attribute-argument-expression : expression
Paragraph 31 An attribute consists of an attribute-name and an optional list of positional and named arguments. 2 The positional arguments (if any) precede the named arguments. 3 A positional argument consists of an attribute-argument-expression; a named argument consists of a name, followed by an equal sign, followed by an attribute-argument-expression, which, together, are constrained by the same rules as simple assignment.) 4 The order of named arguments is not significant.
Paragraph 41 The attribute-name identifies an attribute class. 2 If the form of attribute-name is type-name then this name must refer to an attribute class. 3 Otherwise, a compile-time error occurs. [Example: The example
class Class1 {}
[Class1] class Class2 {} // Error
results in a compile-time error because it attempts to use Class1 as an attribute class when Class1 is not an attribute class. end example]
Paragraph 51 Certain contexts permit the specification of an attribute on more than one target. 2 A program can explicitly specify the target by including an attribute-target-specifier. 3 When an attribute is placed at the global level, a global-attribute-target-specifier is required. 4 In all other locations, a reasonable default is applied, but an attribute-target-specifier can be used to affirm or override the default in certain ambiguous cases (or to just affirm the default in non-ambiguous cases). 5 Thus, typically, attribute-target-specifiers can be omitted except at the global level. 6 The potentially ambiguous contexts are resolved as follows:
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 {}
shows two attribute classes named X and XAttribute. 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 {}
end example]
Paragraph 81 It is a compile-time error to use a single-use attribute class more than once on the same entity. [Example: The example
using System;
[AttributeUsage(AttributeTargets.Class)]
public class HelpStringAttribute: Attribute
{
string value;
public HelpStringAttribute(string value) {
this.value = value;
}
public string Value { get {...} }
}
[HelpString("Description of Class1")]
[HelpString("Another description of Class1")]
public class Class1 {}
results in a compile-time error because it attempts to use HelpString, which is a single-use attribute class, more than once on the declaration of Class1. end example]
Paragraph 91 An expression E is an attribute-argument-expression if all of the following statements are true:
using System;
[AttributeUsage(AttributeTargets.Class)]
public class MyAttribute: Attribute
{
public int P1 {
get {...}
set {...}
}
public Type P2 {
get {...}
set {...}
}
public object P3 {
get {...}
set {...}
}
}
[My(P1 = 1234, P3 = new int[]{1, 3, 5}, P2 = typeof(float))]
class MyClass {}
end example]
| |
| Jagger Software Ltd | |
| Company # 4070126 | |
| VAT # 762 5213 42 |