24.2 Attribute specification

Attribute specification is the application of a previously defined attribute
to a declaration. An attribute is a
piece of additional declarative information that is specified for a
declaration. Attributes can be specified at
global scope (to specify attributes on the containing assembly) and for
type-declarations (§16.5), classmember-
declarations (§17.2), struct-member-declarations (§18.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).
Attributes are specified in attribute sections. An attribute section
consists of a pair of square brackets, which
surround a comma-separated list of one or more attributes. 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. 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 , ]
C# LANGUAGE SPECIFICATION
308
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
An attribute consists of an attribute-name and an optional list of
positional and named arguments. The
positional arguments (if any) precede the named arguments. A positional
argument consists of an attributeargument-
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. The
order of named arguments is not significant.
The attribute-name identifies an attribute class. If the form of
attribute-name is type-name then this name
must refer to an attribute class. 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]
Certain contexts permit the specification of an attribute on more than one
target. A program can explicitly
specify the target by including an attribute-target-specifier. When an
attribute is placed at the global level, a
global-attribute-target-specifier is required. 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
Chapter 24 Attributes
309
affirm the default in non-ambiguous cases). Thus, typically,
attribute-target-specifiers can be omitted
except at the global level. The potentially ambiguous contexts are resolved
as follows:
? An attribute specified on a delegate declaration can apply either to the
delegate being declared or to its
return value. In the absence of an attribute-target-specifier, the
attribute applies to the delegate. The
presence of the type attribute-target-specifier indicates that the
attribute applies to the delegate; the
presence of the return attribute-target-specifier indicates that the
attribute applies to the return value.
? An attribute specified on a method declaration can apply either to the
method being declared or to its
return value. In the absence of an attribute-target-specifier, the
attribute applies to the method. The
presence of the method attribute-target-specifier indicates that the
attribute applies to the method; the
presence of the return attribute-target-specifier indicates that the
attribute applies to the return value.
? An attribute specified on an operator declaration can apply either to the
operator being declared or to its
return value of this declaration. In the absence of an
attribute-target-specifier, the attribute applies to the
operator. The presence of the method attribute-target-specifier indicates
that the attribute applies to the
operator; the presence of the return attribute-target-specifier indicates
that the attribute applies to the
return value.
? An attribute specified on an event declaration that omits event accessors
can apply to the event being
declared, to the associated field (if the event is not abstract), or to the
associated add and remove
methods. In the absence of an attribute-target-specifier, the attribute
applies to the event declaration.
The presence of the event attribute-target-specifier indicates that the
attribute applies to the event; the
presence of the field attribute-target-specifier indicates that the
attribute applies to the field; and the
presence of the method attribute-target-specifier indicates that the
attribute applies to the methods.
? An attribute specified on a get accessor declaration for a property or
indexer declaration can apply either
to the associated method or to its return value. In the absence of an
attribute-target-specifier, the
attribute applies to the method. The presence of the method
attribute-target-specifier indicates that the
attribute applies to the method; the presence of the return
attribute-target-specifier indicates that the
attribute applies to the return value.
? An attribute specified on a set accessor for a property or indexer
declaration can apply either to the
associated method or to its lone implicit parameter. In the absence of an
attribute-target-specifier, the
attribute applies to the method. The presence of the method
attribute-target-specifier indicates that the
attribute applies to the method; the presence of the param
attribute-target-specifier indicates that the
attribute applies to the parameter.
? An attribute specified on an add or remove accessor declaration for an
event declaration can apply either
to the associated method or to its lone parameter. In the absence of an
attribute-target-specifier, the
attribute applies to the method. The presence of the method
attribute-target-specifier indicates that the
attribute applies to the method; the presence of the param
attribute-target-specifier indicates that the
attribute applies to the parameter.
An implementation may accept other attribute target specifiers, the purpose
of which is implementationdefined.
However, an implementation that does not recognize such a target, shall
issue a warning.
By convention, attribute classes are named with a suffix of Attribute. An
attribute-name of the form typename
may either include or omit this suffix. If an attribute class is found both
with and without this suffix,
an ambiguity is present, and a compile-time error shall be issued. If the
attribute-name is spelled such that
its right-most identifier is a verbatim identifier (§9.4.2), then only an


attribute without a suffix is matched,
thus enabling such an ambiguity to be resolved. [Example: The example
using System;
[AttributeUsage(AttributeTargets.All)]
public class X: Attribute
{}
[AttributeUsage(AttributeTargets.All)]
public class XAttribute: Attribute
{}
C# LANGUAGE SPECIFICATION
310
[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]
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]
An expression E is an attribute-argument-expression if all of the following
statements are true:
? The type of E is an attribute parameter type (§24.1.3).
? At compile-time, the value of E can be resolved to one of the following:
A constant value.
A System.Type object.
A one-dimensional array of attribute-argument-expressions.
[Example: For example:
Chapter 24 Attributes
311
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]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值