Attributes

[[ target :]? attribute-name (
positional-param+ |
[ named-param = expression ]+ |
positional-param +, [ named-param = expression ] + )?]

Attributes are language constructs that can decorate a code element (assemblies, modules, types, members, return values, and parameters) with additional information.

In every language, you specify information associated with the types, methods, parameters, and other elements of your program. For example, a type can specify a list of interfaces that it derives from, or a parameter can specify how its values are to be passed with modifiers such as the ref modifier in C#. The limitation of this approach is that you can only associate information with code elements using the predefined constructs that the language itself provides.

Attributes allow programmers to add to the types of information associated with these code elements. For example, serialization in the .NET Framework uses various serialization attributes applied to types and fields to define how these code elements are serialized. This is more flexible than requiring the language to have special syntax for serialization.

Attribute Classes

An attribute is defined by a class that inherits (directly or indirectly) from the abstract class System.Attribute . When specifying an attribute on an element, the attribute name is the name of the type. By convention the derived type name ends with the word “Attribute”, but this suffix isn’t required.

In this example we specify that the Foo class is serializable using the Serializable attribute:

[Serializable]
public class Foo {...}

The Serializable attribute is actually a type declared in the System namespace, as follows:

class SerializableAttribute : Attribute {...}

We could also specify the Serializable attribute using its fully qualified typename, as follows:

[System.SerializableAttribute]
public class Foo {...}

The preceding two examples that use the Serializable attribute are semantically identical.

Tip

The C# language and the BCL include a number of predefined attributes. For more information on the other attributes included in the BCL, and on creating your own attributes, see Section 3.11 in Chapter 3.

Named and Positional Parameters

Attributes can take parameters, which specify additional information on the code element beyond the mere presence of the attribute.

In this next example, we specify that the class Foo is obsolete using the Obsolete attribute. This attribute allows you to include parameters that specify a message and indicate whether the compiler should treat the use of this class as an error:

[Obsolete("Use Bar class instead", IsError=true)]
public class Foo {...}

Attribute parameters fall into one of two categories: positional and named parameters. In the preceding example, Use Bar class instead is a positional parameter, and IsError=true is a named parameter.

The positional parameters for an attribute correspond to the parameters passed to one of the attribute type’s public constructors. The named parameters for an attribute correspond to the set of public read-write or write-only instance properties and fields on the attribute type.

When specifying an attribute on an element, positional parameters are mandatory, and named parameters are optional.

Since the parameters used when specifying an attribute are evaluated at compile time, they are generally limited to constant expressions.

Attribute Targets

Implicitly, the target of an attribute is the code element it immediately precedes. Sometimes it is necessary to explicitly specify that the attribute applies to a particular target.

In the beta 1 version of the C# compiler, the valid targets are assembly and module . In future versions of the language, this list of explicit targets is expected to expand to include parameters, return values, etc.

Here is an example that uses the CLSCompliant attribute to specify the level of CLS compliance for an entire assembly:

[assembly:CLSCompliant(true)]

Specifying Multiple Attributes

You can specify multiple attributes on a single code element. Each attribute can be listed within the same pair of square brackets (separated by a comma), in separate pairs of square brackets, or any combination of the two.

Consequently, the following three examples are semantically identical:

[Serializable, Obsolete, CLSCompliant(false)]
public class Bar {...}

[Serializable] 
[Obsolete] 
[CLSCompliant(false)]
public class Bar {...}

[Serializable, Obsolete] 
[CLSCompliant(false)]
public class Bar {...}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.90.182