C# Attributes Tutorial For Beginners With Examples

Attributes allow declarative information or metadata to be associated with an assembly, class, method, property and other programming elements in C#.
In C#, the Attribute names are enclosed in square brackets [] and mentioned before the class or method name. Some commonly used Attribute names are System.Serializable and System.Obsolete.

Features of C# Attributes

The important features of C# Attributes are discussed below:
  • Attributes allows metadata to be added to an assembly or programming element. Metadata is additional data or information about a type or assembly.
  • .NET allows one or more attributes to be added to an assembly or programming element like class, method, properties etc.
  • Internally all the Attributes are defined as a class in .NET Framework.
  • Like methods and properties, attributes can also have arguments.
  • The metadata associated with a programming element can be checked by the same program or another program using a process called as Reflection.

Example of an Attribute

Lets see some examples of Attributes used at Class and Assembly level.
Below is an example of a class level Attribute. In this example the Attribute Serializable is applied to the class ReadData.
    [System.Serializable]
    public class ReadData
    {
        void ReadFile()
        {
            //Code to read file.
        }

        void ReadMemory()
        {
            //Code to read memory.
        }
    }
        
Next is a example showing a assembly level attribute. In a C# project, the assembly level attributes can be found under [Project Name]/Properties/AssemblyInfo.cs. The below example provides a glimpse of that.
    [assembly: AssemblyTitle("Tutorial")]
    [assembly: AssemblyDescription("Tutorial Site")]
    [assembly: AssemblyCompany("tutorialnode.com")]
        

Classification of Attributes

Attributes in C# are classified as below:
  • Pre-defined or Reserved attributes - These attributes are available as part of .NET framework base class libraries.
  • Custom attributes - These attributes are created using .NET code to match a specific requirement in a project.

Pre-defined Attributes

Below pre-defined or reserved Attributes will be discussed in this tutorial. MSDN has an exhaustive list of all the predefined attributes provided by C# .NET.
  • AttributeUsage
  • Conditional
  • Obsolete
Before exploring the custom attributes we will discuss the above reserved attributes first.

AttributeUsage Attribute

AttributeUsage is a pre-defined or reserved attribute which determines the usage of a custom Attribute class.
The name AttributeUsage is an alias for the AttributeUsageAttribute class found in the System namespace.

Example of AttributeUsage Attribute

In the below example an AttributeUsage Attribute is applied to a custom attribute classValidationAttribute.
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public class ValidationAttribute : System.Attribute
    {
        //Custom code
    }
        

Parameters of Attributeusage Attribute

  • AttributeTargets - This is a mandatory parameter that decides the code entities on which a custom Attribute can be used.
  • AllowMultiple - AllowMultiple is an optional parameter that determines whether a custom Attribute can be applied multiple times to an code entity.
  • Inherited - This parameter is also optional and determines whether a custom Attribute can be inherited by other classes.

Conditional Attribute

Conditional Attributes makes execution of C# methods conditional. So, using these it is possible to skip the execution of a method completely. Conditional Attribute achieves this by using preprocessing identifier. In other words Conditional Attribute makes the execution of a method dependent on a preprocessing identifier.
Conditional Attributes can also be applied to classes which inherit from System.Attribute class. They cannot be applied to any other class or programming elements. Additionally, this attribute has only one parameter of type string.
The name Conditional is an alias for the ConditionalAttribute class found in the System.Diagnostics namespace.

Example of a Conditional Attribute

A simple example is shown below. In the below example ALLOW is a preprocessing identifier. Conditional attribute is applied to method Display1. Since the preprocessing identifier ALLOW is defined in the beginning of the program so the method Display1 is executed.
To check the usage of preprocessing identifier, remove the statement '#define ALLOW', rebuild and run the application.
        
    #define ALLOW
    using System;
    using System.Diagnostics;

    class Program
    {
        [Conditional("ALLOW")]
        static void Display1()
        {
            Console.WriteLine("This is a conditional method");
        }
        static void Display2()
        {
            Console.WriteLine("This is a standard method");
        }
        public static void Main()
        {
            Display1();
            Display2();
            Console.ReadKey();
        }
    }
        
Output:
This is a conditional method
This is a standard method
The preprocessor identifier can be any custom name.

Conditional Methods

The method on which a Conditional Attribute is applied is called as Conditional Method. This method should follows the below rules.
  • A Conditional Method must be part of a Class or Struct. It cannot be part of a Interface.
  • The return type should always be void.
  • A Conditional Method cannot have an override keyword. It can have the virtual keyword though.
  • A method which is part of an Interface implementation can be used as a Conditional Method.

Obsolete Attribute

A program element can be marked as obsolete using the Obsolete Attribute. Which means in the future versions of a product this particular program element will be removed.
Obsolete Attribute cannot be used for assemblies, parameters, return values and modules.
Although a program element marked as obsolete can still be used but when done so the compiler throws a warning message.
Similar to AttributeUsage and Conditional Attributes, the name Obsolete is also an alias for the ObsoleteAttribute class found in the System namespace.

Example of an Obsolete Attribute

In the below example the class Customer has a property Name which is marked as obsolete. The program still executes successfully but with warning messages.
    using System;

    public class Customer
    {
        [Obsolete("Not used anymore", false)]
        public string Name
        {
            get;
            set;
        }

        public string CustomerName
        {
            get;
            set;
        }
    }

    class Program
    {
        public static void Main()
        {
            Customer customer = new Customer();
            customer.Name = "Bing";

            Console.Write(customer.Name);
            Console.ReadKey();
        }
    }
        
Output:
Bing

Parameters of an Obsolete Attribute

An Obsolete Attribute has two optional parameters.
In the above example two parameters are used. The first parameter name is message which can be used to provide information about the deprecated program element. The second parameter is boolean and is named as error. When the error parameter is true then the compiler throws an error when the program element to which the Obsolete Attribute is applied is used. If it is false then the compiler only generates warning message.
When a single parameter is used then it should always be the message parameter. When theerror parameter is not used then the default value will be false.

Custom Attributes

A Custom Attribute in C# can be created by inheriting from System.Attribute class.
Custom Attributes are used to store custom declarative information that can be retrieved at run time. Each Attribute should have at least one constructor.

Example of a Custom Attribute

While naming an Attribute the name 'Attribute' should be added to the end. This helps to create the alias name for the Attribute. In the below example a custom Attribute named as InformationAttribute is created. While using this Attribute only the name 'Information' is used.
An AttributeUsage Attribute has been added to the Custom Attribute Information to define the usage of the Information Attribute.
In the below example the message parameter is called as positional parameter. In fact all the parameters which are part of the constructor of an Attribute is called as positional parameters whereas any public property or field of an Attribute is called as named parameter. In this example reference is a named parameter.
    using System;

    [AttributeUsage(AttributeTargets.All)]
    public class InformationAttribute : Attribute
    {
        private string message;
        public string reference;

        public InformationAttribute(string message)
        {
            this.message = message;
        }
    }

    public class Customer
    {
        [Information("This property is used for the customer name", reference = "http://tutorialnode.com")]
        public string Name
        {
            get;
            set;
        }
    }

    class Program
    {
        public static void Main()
        {
            Customer customer = new Customer();
            customer.Name = "John Doe";
            Console.Write(customer.Name);
            Console.ReadKey();
        }
    }        
    
Output:
John Doe
The metadata added by Attributes can be retrived using a process called as Reflection. This will be discussed in a separate chapter.