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.
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:
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.
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.
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();
}
}
}
Conditional Attribute:
Yes i Am Agree:
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
)]
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.
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.
“
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 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());
}
}
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.