Posted by: Zeeshan Amjad | July 16, 2009

Writing Custom Attribute in C#


Attributes is very powerful and interesting feature in .Net. It introduces the declarative programming style within your program. Declarative programming means one write a program without any control flow. Declarative program made up with just declarations and their relationship only such as HTML that has only tags but not control structure.

Attributes in .Net are just like declarative programming style. It tells the compile to emit some metadata that may be useful runtime, compile time or both. Here is one simple WPF program to show one predefined attributes of .Net.

  1: using System;
  2: using System.Windows;
  4: public class wpf
  5: {
  6:     [STAThread]
  7:     public static void Main()
  8:     {
  9:         Window win = new Window();
 10:         win.Title = "Hello World";
 12:         Application app = new Application();
 13:         app.Run(win);
 14:     }
 15: }

Here [STAThread] is predefined .Net attribute. This attribute set the application COM threading model to single threaded apartment.

Some declarative language gives flexibility to enhance its declarations, such as XML. In XML one may define his own new tags. Similarly .Net platform provides flexibility to add new attributes. In other word its means adding a new keyword to the language. In .Net if one has to define a new attribute then it must be inherited by Attribute class. Here is one example.

  1:     public sealed class MyAttribute : Attribute
  2:     {
  3:     }

It is not necessary to make attribute sealed. This attribute can be applied to any class, structure, method, event, enum, delegate, parameter etc. Here is one typical example of using this attribute.

  1:         [MyAttribute]
  2:         static void PrintMessage([MyAttribute]String msg)
  3:         {            
  4:             System.Console.WriteLine(msg);
  5:         }

Here we are using our newly created attribute to not only with method but as well as with its parameter too.

If we want to restrict the use our customized attribute to some specific type or types then we can do it with the help of one built in attribute name “AttributeUsage”. Here is one example.

  1:     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
  2:     public sealed class MyAttribute : Attribute
  3:     {
  4:     }

This attribute can be used only with class or structure type. There will be compilation error if we try to use it with other types. Let’s take a look at one example of using Custom attribute.

Here we are going to make one small class for student. Just for the simplicity, we skip rest of the detail from the class except the name, address and GPA. Because demographic information is required only for statistical purpose therefore we made it as a custom attribute and store the residency and ethnicity as a custom attribute. Even further we made the ethnicity information optional in custom attribute. Here is out sample code of it.

  1:     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
  2:     public sealed class DemographiInfoAttribute : Attribute
  3:     {
  4:         private ResidentStatus status;
  5:         private String ethnicity;
  7:         public DemographiInfoAttribute(ResidentStatus status)
  8:         {
  9:             this.status = status;
 10:         }
 12:         public String Ethnicity
 13:         {
 14:             get { return ethnicity; }
 15:             set { ethnicity = value; }
 16:         }
 17:     }

This attribute can be applied to only classes or structures. It has one positional parameter passed as a parameter in the constructor and one optional parameter defined as a field. Because field is private therefore we make one property to expose it. Here is the usage of this custom attribute.


  1:     public enum ResidentStatus
  2:     { InCounty, OutOfCounty, OutOfState, International }
  4:     [DemographiInfo(ResidentStatus.InCounty, Ethnicity="Asian")]
  5:     public class Student
  6:     {
  7:         public String Name
  8:         { get; set; }
 10:         public String Address
 11:         { get; set; }
 13:         public float GPA
 14:         { get; set; }
 15:     }

Leave a Reply

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

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

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s


%d bloggers like this: