Posted by: Cirilo Meggiolaro | 03/2/2009

Tip of the day #139 – Custom attributes

Attributes are used as metadata for assembly classes, methods, enumerators and other elements and it may be accessed in runtime using reflection.

Let’s check today how to create custom attributes that you may use for your classes, methods, enums and so on.

How to…

A custom attribute class is a regular class that inherits from the System.Attribute base type. So, if you want to create your custom attribute called Documentation your class will be similar to the following:

public class Documentation : System.Attribute { }

An attribute that doesn’t store any additional metadata information acts just as a flag. To improve and make your custom attribute more useful, you may add read-write properties like the following code demonstrates:

public class Documentation : System.Attribute
{
    public string Description { get; set; }
}

Using properties you are able to use the syntax PropertyName=Value to define its value. This syntax is also known as named parameters.

You may also create a class constructor to store information without using named parameters as described above. Your class will be similar to the following code snippet:

public class Documentation : System.Attribute
{
    private string _description = string.Empty;

    public Documentation(string description)
    {
        this._description = description;
    }
}

If you name your custom attribute class with the word “attribute” as suffix you’ll be able use two different syntaxes to define the metadata: Documentation or DocumentationAttribute.

Defining constraints

To specify constraints for your custom attribute class, add an AttributeUsage attribute and define the following:

1. A flag of elements on which the custom attribute is valid to be used. The following items are available:

  • Assembly;
  • Module;
  • Class;
  • Struct;
  • Enum;
  • Constructor;
  • Method;
  • Property;
  • Field;
  • Event;
  • Interface;
  • Parameter;
  • Delegate;
  • ReturnValue;
  • GenericParameter;
  • All.

2. Define if the attribute may be used more than once for the same element, specifying the AllowMultiple Boolean parameter;

3. Define if the attribute must be used by derived classes specifying the Inherited Boolean parameter. The final version of our custom attribute is shown below:

[System.AttributeUsage(AttributeTargets.Class, Inherited=true, AllowMultiple=false)]
public class DocumentationAttribute : System.Attribute
{
    private string _description = string.Empty;

    public DocumentationAttribute(string description)
    {
        this._description = description;
    }

    public string Scope { get; set; }
}

How to use the attribute

The following code shows how to use the custom attribute. You may omit the word attribute from the custom attribute name that is still recognized.

[Documentation(“This class stores weak references of order objects.”, Scope=“This class must be used by the billing system only.”)]
public class OrderCollection { }


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: