AddThis Social Bookmark Button

Print

Programming C#: Attributes and Reflection
Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Declaring an Attribute

Attributes, like most things in C#, are embodied in classes. To create a custom attribute, you derive your new custom attribute class from System.Attribute:



public class BugFixAttribute : System.Attribute

You need to tell the compiler with which kinds of elements this attribute can be used (the attribute target). You specify this with (what else?) an attribute:

[AttributeUsage(AttributeTargets.Class |
    AttributeTargets.Constructor |
    AttributeTargets.Field |
    AttributeTargets.Method |
    AttributeTargets.Property,
    AllowMultiple = true)]

AttributeUsage is an attribute applied to attributes: a meta-attribute. It provides, if you will, meta-metadata -- that is, data about the metadata. For the AttributeUsage attribute constructor, you pass two arguments. The first argument is a set of flags that indicate the target -- in this case, the class and its constructor, fields, methods, and properties. The second argument is a flag that indicates whether a given element might receive more than one such attribute. In this example, AllowMultiple is set to true, indicating that class members can have more than one BugFixAttribute assigned.

Naming an Attribute

The new custom attribute in this example is named BugFixAttribute. The convention is to append the word Attribute to your attribute name. The compiler supports this by allowing you to call the attribute with the shorter version of the name. Thus, you can write:

[BugFix(123, "Jesse Liberty", "01/01/05", Comment="Off by one")]

The compiler will first look for an attribute named BugFix and, if it does not find that, will then look for BugFixAttribute.

Constructing an Attribute

Every attribute must have at least one constructor. Attributes take two types of parameters, positional and named. In the BugFix example, the programmer's name and the date are positional parameters, and comment is a named parameter. Positional parameters are passed in through the constructor and must be passed in the order declared in the constructor:

public BugFixAttribute(int bugID, string programmer, 
string date)
{
    this.bugID = bugID;
    this.programmer = programmer;
    this.date = date;
}

Named parameters are implemented as properties:

public string Comment
{
     get
     {
         return comment;
     }
     set
     {
         comment = value;
     }
}

It is common to create read-only properties for the positional parameters:

public int BugID
{
     get
     {
         return bugID;
     }
}

Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Next Pagearrow