The Use of Attribute in .NET Programming (Part 2)

The support for Attribute in the .NET Framework is a brand-new capability, and this support comes from its Attribute class. Using this class appropriately in your program, or using it flexibly and cleverly, will give your program some ability that was very hard to achieve in past programming. Let’s look at an example: Suppose you are a member of a project development team, and you want to track code-review information. Usually you can save the code-review information in a database for querying; or write the information into code comments, so you can see the code-review information while reading the code. We know .NET components are self-describing, so can the code describe its own review information? That way we can keep the information together with the code, and also get the information through the code’s self-description. The answer is to use Attribute. The steps and code below tell you how to do it: First, we create a custom Attribute, and preset that our Attribute will be applied to class elements to get a class’s code-review information.

using System;
using System.Reflection;

[AttributeUsage(AttributeTargets.Class)] // remember the previous section?
public class CodeReviewAttribute : System.Attribute // define a CodeReview Attribute
{
 private string reviewer;  // code reviewer
 private string date;      // review date
 private string comment;   // review result info

 // parameterized constructor
 public CodeReviewAttribute(string reviewer, string date)
 {
  this.reviewer=reviewer;
  this.date=date;
 }

 public string Reviewer
 {
  get
  {
   return reviewer;
  }
 }

 public string Date
 {
  get
  {
   return date;
  }
 }

 public string Comment
 {
  get
  {
   return comment;
  }
  set
  {
   comment=value;
  }
 }
}

Our custom CodeReviewAttribute is no different from an ordinary class; it derives from Attribute, and through AttributeUsage indicates that our Attribute can only be applied to class elements.

The second step is to use our CodeReviewAttribute. Suppose we have a class MyClass written by Jack, the reviewer is Niwalker, and the review date is July 9, 2003. Then we apply the Attribute as follows:

[CodeReview("Niwalker","2003-7-9",Comment="Jack's code")]
public class MyClass
{
 // class member definitions
}

When this code is compiled, the compiler will call the CodeReviewAttribute constructor and pass “Niwalker” and “2003-7-9” as the constructor’s parameters respectively. Note that there is also an assignment to the Comment property in the parameter list — this is a special way of Attribute, where you can set more public properties of the Attribute (if any). It should be pointed out that .NET Framework 1.0 allowed assigning to private properties, but .NET Framework 1.1 no longer allows this — you can only assign to public properties.

The third step is to retrieve the information we need, which is done through .NET reflection. I don’t intend to explain reflection here due to space limitations; maybe I’ll write a separate article about reflection later.

class test
{
   static void Main(string[] args)
   {
      System.Reflection.MemberInfo info=typeof(MyClass); // get MyClass class info via reflection

// get the custom Attribute applied to the MyClass class
      CodeReviewAttribute att=
                 (CodeReviewAttribute)Attribute.GetCustomAttribute(info,typeof(CodeReviewAttribute));
      if(att!=null)
      {
          Console.WriteLine("代码检查人:{0}",att.Reviewer);
          Console.WriteLine("检查时间:{0}",att.Date);
          Console.WriteLine("注释:{0}",att.Comment);
      }
   }
}

In this example, Attribute plays the role of adding extra information to a class, and it does not affect the behavior of the MyClass class. Through this example, we roughly know how to write a custom Attribute, and how to use it in an application. In the next section, I’ll introduce how to use Attribute to automatically generate the code for an ADO.NET data-access class. (To be continued)