# .NET Development Foundation/Attributes
## Annexes: Building custom attributes

Original text for this page authored by William "Scott" Baker

### Attributes Summary

Attributes are a way to "tag" elements of your code's metadata with descriptive information that can be accessed at runtime using reflection. Attributes must derive from System.Attribute, either directly or indirectly. A multitude of attributes exist in the .NET framework; you can also define your own. There are three aspects to using attributes in your code:
* Defining a custom attribute class, which involves:
** Assigning the AttributeUsageAttribute attribute to your class.
** Writing the code to define your custom attribute class.
** Creating the parameters for your class.
* Assigning an attribute to a code member.
* Retrieving attribute information at runtime.

### Creating a Custom Attribute Class

As previously mentioned, there are several predefined attributes in the .NET Framework; you may have already used them in your code. The XML parser in particular relies heavily on attributes when (de)serializing objects. You can also define your own custom attributes, as we will show here. Defining a custom attribute involves three steps:
* Assigning the AttributeUsageAttribute attribute to your class.
* Writing the code to define your custom attribute class.
* Creating the parameters for your class.

#### Assigning the "AttributeUsageAttribute" To Your Class

Notice the use of "AttributeUsage" vs. "AttributeUsageAttribute". By convention, all attributes are named with the "Attribute" suffix - but the suffix can be omitted when used in code. This holds true for user defined attributes as well; the QualityCheckAttribute attribute could be referenced as either:
The AttributeUsageAttribute has three members: ValidOn, AllowMultiple and Inherited.
* The ValidOn member accepts AttributeTargets enum values, and restricts your attribute to the code types you specify. The default value is AttributeTargets.All. You can confine your attribute to classes, enums, return values or any of the list below:
You can also combine target types as a bitwise OR operation to specify multiple acceptable values:
* AllowMultiple is a boolean value that determines whether or not an attribute can be applied more than once to a given member. The default value is false. The example below illustrates multiple instances of the same attribute on an element of code:
* The Inherited member determines whether attributes set on a class will be inherited by classes further down the inheritance tree. The default value is true:

#### Defining A Custom Attribute Class

* Attributes are classes that inherit from System.Attribute, either directly or indirectly:
* Attribute classes have the AttributeUsageAttribute attribute:
As previously mentioned, the use of AttributeUsageAttribute is required in VB. In C#, it is automatically applied with the default values if not declared.

#### Creating Parameters For An Attribute
##### Named Parameters

Keep in mind that a variable in your code can be both a positional parameter and a named parameter. If we were to add public properties for the _name and _date fields we could use them either as named parameters or positional parameters. Of course, this is not a recommended practice: required parameters should be positional and optional parameters should be named.

### Assigning An Attribute To A Code Member

You have already seen examples of assigning an attribute to a code member. However, there are some points that must be clarified.
* Disambiguation is the clarification of the use of an attribute on a code member.
* Syntax - there is more than one way to apply multiple attributes.

#### Disambiguation

Disambiguation resolves these issues. By specifying the code type the attribute is applied to, we are able to resolve the confusion. The code below shows that the attribute applies to the return value:
The table below lists all declarations where attributes are allowed; for each declaration, the possible targets for attributes on the declaration are listed in the second column. Targets in bold are the defaults.
One would think that the AttributeUsageAttribute's AttributeTargets in an attribute's definition would help to prevent this confusion: one would be wrong. The compiler does not use the AttributeUsageAttribute information when resolving conflicts. Even if you define an attribute to apply only to a specific type, for instance AttributeTargets.Return, you must still clarify that it applies to the return type when applying the attribute or the compiler will use the default target method type, and throw an error.

#### Syntax: Applying Multiple Attributes

The two are equivalent. Keep in mind that if you are going to specify more than one attribute in a single brace, they must apply to the same target type. If not, you must give each type a separate declaration:

### Retrieving Attribute Information At Runtime

Being able to declare and apply attributes is not very helpful unless we can retrieve that data and do something with it. Fortunately, its a straightforward process. There are three basic scenarios that will be addressed:
* Retrieve a single attribute from a member.
* Retrieve multiple attributes from a member.
* Retrieve attributes of a single type from multiple members.

#### Retrieving A Single Attribute From A Member

To access attribute information:
* Declare an instance of the attribute type.
* Use the Attribute.GetCustomAttribute(type, typeof) method to read the attribute into the instance.
* Use the properties of the instance to read the values.
The example code below declares a class ExampleClass with a QualityCheck attribute. The GetSingleAttribute method accepts a target member type and the type of attribute you're looking for. The Attribute.GetCustomAttribute method retrieves the attribute information into the attr object, from which we can read the all-important IsApproved property:
An important factor to keep in mind is that the GetCustomAttribute method is designed to read one and only one attribute. GetCustomAttribute actually checks to see if more than one attribute matches - if there is no match it returns null, but if there is more than one match it will throw an AmbiguousMatchException. When checking for attributes the only time it is safe to use GetCustomAttribute is when the attribute's definition states [AttributeUsage(AllowMultiple=false)].

#### Retrieving Multiple Attributes From A Member

Reading multiple instances of an attribute on a member isn't much different than reading one; to read multiple attributes use the plural GetCustomAttributes, which returns an array of attributes. You can then iterate through the resultant array and read the values:

#### Retrieving A Single Attribute Type From Multiple Members

What if you want to do something a little more complex, like checking each method in a class for a QualityCheck attribute? Thanks to the System.Reflection namespace, we don't have to even break a sweat. Simply read all the members (methods, in this instance) into a MemberInfo array and iterate through them:

### External links

* MSDN2 .NET Framework Developer's Guide: Attributes Overview
* MSDN2 C# Programming Guide: Entry for Attributes
* The C# Station Tutorial - Lesson 16: Using Attributes
* Bill Bozeman's weblog on attributes