Topic : Attributes in C# Programming Language: Pre-Defined Attributes | Custom Attributes

Attributes:

Attribute is Nothing, but a Piece of Information. This information can be attached to our Method, class, namespace, etc. Attributes are the part of Our code this makes developers life easier as he can see the information right Upfront in the Code while he is calling the method or assessing the class and take actions accordingly.

Attributes are a New kind of declarative information. we can use attributes to define both design-level information, (such as Help file, URL for Documentation) and Run-time Information (Such as Associating XML field with class Field). we can also create "Self-describing" components using Attributes.



  • Types of Attributes:

    Attributes are of Two Types:
    » Pre-defined Attributes:
    » Custom Attributes:



Pre-Defined Attributes:

C# Provide a small set of Pre-defined Attributes. Before Learning how to create our Own Custom Attributes, We need to look at how to use pre-defined attributes: The .NET Framework Provides few pre-defined attributes, some of them are:


  • » AttributeUsage:
    » Conditional:
    » Obsolete:



AttributeUsage:

This Pre-defined Attribute Describes how a custom Attribute class can be used. It Specifies the Types of Items to which the attribute can be Applied.


  • The AttributeUsage Attribute has the following three parameters:
    » ValidOn:
    Positional Parameter that defines the Program Elements that are Eligible to use the attribute. This Parameter's value must use one of the values from the AttributeTargets Enumeration, listed here.

    AllAssemblyClassEnum
    ConstructorDelegate EventField
    InterfaceMethod ReturnValueStruct
    ModuleParameterProperty

    » AllowMultiple: (Optional)
    Named Parameter that specifies whether an Attribute can be used Multiple times in the same Program element. Its a Boolean value. if this is true, we can use the attribute multiple times in the same Program. and the Default value is false mean we by default, we can't use the attribute multiple times.
    » Inherited: (Optional)
    Named Parameter that Indicates whether the Attribute should be Inherited by Sub-classes of the type. it's a Boolean value. if it is true, the attribute is derived classes. the default value is false, mean not inherited.



Syntax:

We can declare the Attribute using the Square ( [] ) Brackets. The basic syntax for AttributeUsage Attribute is:


 [AttributeUsage( 
    Validon,
    AllowMultiple = allowmultiple ,
    Inherited = Inherited
)
]

The first AttributeUsage argument must be one or more elements of the AttributeTargets enumeration. Multiple target types can be linked together with the OR ( | ) operator, like this:


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



Conditional:

The Conditional Attribute Allows us to create conditional Methods. A Conditional Method is Invoked Only when a Specific value has been defined via #define. otherwise, the method is bypassed.


  • Conditional Methods have a Few Restrictions:
    » Conditional Methods must return void.
    » Conditional Methods Must be member of a Class, not an interface.
    » Conditional methods can't be preceded with the override keyword.



The Basic syntax for Specifying this Attribute is as Follows:


  [conditional(
    Conditional_Symbol
)
]


/*Example: Conditional Attribute - Infobrother*/

#define Yes    //Pre-processing Identifier:
using System;
using System.Diagnostics;

namespace Attrib
{
    class Program
    {
        [Conditional("Yes")]  //Attribute: for "Yes"
        public void agree()
        {
            Console.WriteLine("Yes I Am Agree: ");
        }

        [Conditional("No")]   //Attribute: for "No"
        public void disagree()
        {
            Console.WriteLine("NO I Am not Agree: ");
        }

        static void Main(string[] args)
        {
            Program obj = new Program();
            obj.agree();     //Call Only if "Yes" is #define:
            obj.disagree();  //Call Only if "No" is #define:

            Console.ReadKey();
        }
    }
}


Obsolete:

The Obsolete Attribute Generates a Compile-time warning. when a method has the obsolete attribute, the C# compiler issues a warning if it is called. This help to keep programs correct. Let's suppose we have two same method in the class. one is the old one, and other is new one. so whenever we want to retain the old method in the class, we may mark it as obsolete by displaying a message that, the new method should be used, instead of this old one.

The basic syntax for specifying this attribute is as follows:


[Obsolete(
    Message , Boolean_value
)
]

  • In Above Syntax:

    » The Parameter Message is a string describing the reason why the item is Obsolete and what to use instead.
    » The Parameter Boolean_value is a Boolean value. if its value is true, the compiler should treat the use of the item as an error. Default value is false, its mean compiler generates a warning by default.


Let's have an Example to understand the concept of this Obsolete Attributes.


/*Example: Obsolete Attribute - Infobrother*/

using System;

namespace Attrib
{
    class Program
    {
        //Boolean value is true. so it will treat like an error.
        [Obsolete("You have Updated Method \"NewMethod()\" use that: ", true)]
        public void OldMethod()  
        {
            Console.WriteLine("Its an Old Method: ");
        }

        public void NewMethod()
        {
            Console.WriteLine("Its New Method: ");
        }


        static void Main(string[] args)
        {
            Program obj = new Program();
            obj.OldMethod();    //compiler treat like an error.
            Console.ReadKey();
        }
    }
}


In Above Example We create an Method OldMethod() with obsolete Attribute. In Compile time this Attribute will Generate an Error. As In the Attribute, the Boolean value is true so we can't Run the Program, because the Program will show an error. but if we remove the Boolean value, then the Program will show an Warning. And we can Run the Program.

Attributes Obsolete : infobrother

Constructing The Custom Attribute:

We Can Create Attributes for Private usage or to be published in a Library for Others. The Following Steps are the Definitive Procedure for Creating Custom Attributes.


  • » The Custom Attribute class should be derived from System.Attribute.
    » The Attribute Name should suffixed by Attribute.
    » Set the Probable targets with the AttributeUsage Attribute.
    » Implement the Class Constructor and Write-accessible properties.



To control the usage of custom attributes, We can take advantage of the AttributeUsage class. This class contains properties like, ValidOn, AllowMultiple and Inherited which can be used to control the usage of Our custom attribute.



Let's create Our own custom attribute Named DeBugInfo, Which stores the Information Obtained by debugging any Program. Let it store the Following Information:


  • » The code number for the bug
    » Name of the developer who identified the bug
    » Date of last review of the code
    » A string message for storing the developer's remarks



The DeBugInfo class has three private properties for storing the first three information and a public property for storing the message. Hence the bug number, developer's name, and date of review are the positional parameters of the DeBugInfo class and the message is an optional or named parameter.

Each attribute must have at least one constructor. The positional parameters should be passed through the constructor. The following code shows the DeBugInfo class:



//A custom attribute "BugFix" to be assigned to a class and its members
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]

public class DeBugInfo : System.Attribute
{
   private int bugNo;
   private string developer;
   private string lastReview;
   public string message;
   
   public DeBugInfo(int bg, string dev, string d)
   {
      this.bugNo = bg;
      this.developer = dev;
      this.lastReview = d;
   }
   
   public int BugNo
   {
      get
      {
         return bugNo;
      }
   }
   
   public string Developer
   {
      get
      {
         return developer;
      }
   }
   
   public string LastReview
   {
      get
      {
         return lastReview;
      }
   }
   
   public string Message
   {
      get
      {
         return message;
      }
      set
      {
         message = value;
      }
   }
}


This:

The "this" keyword is a special type of reference variable, that is implicitly defined within each constructor and non-static method as a first parameter of the type class in which it is defined.



Applying The Custom Attribute:

The Attribute is Applied by Placing it Immediately before its target.


[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")]
[DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")]
class Rectangle
{
   //member variables
   protected double length;
   protected double width;
   public Rectangle(double l, double w)
   {
      length = l;
      width = w;
   }
   [DeBugInfo(55, "Zara Ali", "19/10/2012", Message = "Return type mismatch")]
   
   public double GetArea()
   {
      return length * width;
   }
   [DeBugInfo(56, "Zara Ali", "19/10/2012")]
   
   public void Display()
   {
      Console.WriteLine("Length: {0}", length);
      Console.WriteLine("Width: {0}", width);
      Console.WriteLine("Area: {0}", GetArea());
   }
}


NOTE: We Will continue This Example in Our Next Tutorial: Reflection


Accessing Attributes Through Reflection:

One Use which we have discussed till now is for the Developer's that they can see the information while coding and take decision accordingly. Other use is we can read the Information Pro-grammatically using Reflection and act on it. In the Next Tutorial, we retrieve attribute Information using a Reflection class object.



















I Tried my Best to Provide you complete Information regarding this topic in very easy and conceptual way. but still if you have any Problem to understand this topic, or do you have any Questions, Feel Free to Ask Question. i'll do my best to Provide you what you need.

Sardar Omar.
InfoBrother





WRITE FOR INFOBROTHER

Advertising






Advertisement