Attributes and Custom Attributes in C#


Attributes provides the declarative information or metadata with the C# types, properties, methods, classes….etc. We can query this data at run time by using reflection. Attributes have several advantages in C#, we can declare which classes or method serializable, which methods are obsolete, and which methods are exposed in a web service…etc. In this article first we will discuss about predefined attributes in C# and later we will discuss how to create custom attributes in C#.

There are several predefined attributes available in C#, here we will discuss about some of most useful attributes. Attributes are special classes which can applied to types, properties, methods, classes…etc at design time to declare the information and later we can query these attributes to retrieve the declared information by using System.Reflection.

Sometimes we may require to force our client to use new methods instead of old methods, but we can’t delete old methods because client already using the old methods. We have to develop a mechanism to inform the client about new methods. We can achieve this by using Obsolete attribute in C# as shown below.

public class Employee

{

        [Obsolete("Use NewGetEmployeeDetails", false)]

        public string OldGetEmployeeDetails(int iId)

        {

            return "Employee Details";

        }

 

        public string NewGetEmployeeDetails(int iId)

        {

            return "New Employee Details Class";

        }

}

As shown above we have old method OldGetEmployeeDetails() which was already used by the client. To inform the client about new method availability we just applied the Obsolete attribute on it with the required information. We are passing the second parameter as false for the Obsolete attribute which displays just warning message to client as shown below.


If you want to display compile error instead of warning message just pass second parameter as true instead of false as shown below.

public class Employee

{

        [Obsolete("Use NewGetEmployeeDetails", true)]

        public string OldGetEmployeeDetails(int iId)

        {

            return "Employee Details";

        }

 

        public string NewGetEmployeeDetails(int iId)

        {

            return "New Employee Details Class";

        }

}

 

Above code displays the error message to client while using OldGetEmployeeDetails() method. There are several predefined attributes like Conditional, DllImport, SuppressIldasmAttribute, WebMethod, Serializable, and many other attributes for different purpose. WebMethod is popular attribute used to expose the methods through web service. By using Serializable attribute we can expose any method or class as serializable to the client.

We can create custom attribute in C# to provide the specific functionality which is not available already in .Net. We can declare the attribute usage while creating the attribute as shown below.

[AttributeUsage(

          AttributeTargets.Class |

          AttributeTargets.Method,

          AllowMultiple = true)]

 

To create custom attribute open Microsoft Visual Studio 2015 => create Windows Application and name it as CsharpCustomAttributes. Add new class to the project and name it as HelpAttribute. To create the custom attribute we have to inherit from Attribute class. Here we create the HelpAttribute class to provide the information about the methods, classes, types, properties….atc for any type in C# as shown below.

using System;

 

namespace CSharpCustomAttributes

{

    [AttributeUsage(AttributeTargets.All, AllowMultiple = false)]

    public class HelpAttribute : Attribute

    {

        public readonly string sInformation;

 

 

        public HelpAttribute(string sInformation)

        {

            this.sInformation = sInformation;

        }

 

    }

}

 

As shown above we have created the HelpAttribute which takes information of string type as input. We declare this attribute AttributeTarget as all and AllowMultiple as false that means we can apply this attribute for any type in C# but not more than once. We can change AttributeTarget to Class or Method to restrict this attribute to only for classes or method. If we change the AllowMultiple to true, then we can apply attribute more than once. Let’s apply this attribute to our Employee class as shown below.

[Help("This is EMployee Class")]

public class Employee

{

        [Help("This method provides Employee Details based on given Employee Id")]

        public string GetEmployeeDetails(int iId)

        {

            return "New Employee Details Class";

        }

}

As shown above we are applying the Help attribute to Employee class and GetEmployeeDetails() method because we declare the Help attribute usage as AttributeTargets.All. If we try to apply the Help attribute more than once, we will get the compile time error as shown below.

This is because we declare the Help Attribute as AllowMultiple = false.

To retrieve the attributes values of any class at run time we have to use Reflection. Retrieve the Employee class attributes at run time as shown below.

private void Form1_Load(object sender, EventArgs e)

{

            HelpAttribute attr = (HelpAttribute)Attribute.GetCustomAttribute(typeof(Employee), typeof(HelpAttribute));

            MessageBox.Show("The Employee Class Attribute Information: " + attr.sInformation);

}

The above code displays only Employee class information. The below code displays the GetEmployeeDetails() method attribute information.

private void Form1_Load(object sender, EventArgs e)

{

            HelpAttribute attr = (HelpAttribute)Attribute.GetCustomAttribute(typeof(Employee).GetMethod("GetEmployeeDetails"), typeof(HelpAttribute));

            MessageBox.Show("The GetEmployeeDetails() method Attribute Information: " + attr.sInformation);

}

If you want to apply attribute multiple times, change Help attribute declaration as shown below.

using System;

 

namespace CSharpCustomAttributes

{

    [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]

    public class HelpAttribute : Attribute

    {

        public readonly string sInformation;

 

 

        public HelpAttribute(string sInformation)

        {

            this.sInformation = sInformation;

        }

 

    }

}

 

Then apply multiple attributes of Help type to classes or methods as shown below.

[Help("This is Employee Class")]

public class Employee

{

        [Help("This is GetEmployeeDetails")]

        [Help("This method provides Employee Details based on given Employee Id")]

        public string GetEmployeeDetails(int iId)

        {

            return "New Employee Details Class";

        }

}

Here we applied the Help attribute multiple times to GetEmployeeDetails() method. We can retrieve the information from multiple times declaration as shown below by using GetCustomAttributes() method.

private void Form1_Load(object sender, EventArgs e)

{

            HelpAttribute[] attrs = (HelpAttribute[])Attribute.GetCustomAttributes(typeof(Employee).GetMethod("GetEmployeeDetails"), typeof(HelpAttribute));

            foreach(HelpAttribute attr in attrs)

            {

                MessageBox.Show("The GetEmployeeDetails() method Attribute Information: " + attr.sInformation);

            }

}

If you want to make available your attribute to only classes change attribute declaration as shown below.

using System;

 

namespace CSharpCustomAttributes

{

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]

    public class HelpAttribute : Attribute

    {

        public readonly string sInformation;

 

 

        public HelpAttribute(string sInformation)

        {

            this.sInformation = sInformation;

        }

 

    }

}

 

The above attribute is available for only classes as we declare the attribute as AttributeTargets.Class. You can make your attribute available for only methods also by making AttributeTargets to Method.

                                                                                                               CSharpCustomAttributes.zip (53.7KB)