應用自定義特性
你現在已經知道在C#代碼裡,在一個類型聲明之前,通過在方括號裡使用特性的名字和參數就可以將其附加到目標類型上。
在下面的代碼裡,把[DefectTrack]特性附加到一對類和一對方法上。
using System ;
using MyAttributeClasses ;
namespace SomeClassesToTest
{
[DefectTrack( "1377", "12/15/02", "David Tansey" ) ]
[DefectTrack( "1363", "12/12/02", "Toni Feltman",
Origin = "Coding: Unhandled Exception" ) ]
public class SomeCustomPricingClass
{
public double GetAdjustedPrice(
double tnPrice,
double tnPctAdjust )
{ return tnPrice + ( tnPrice * tnPctAdjust ) ; }
[DefectTrack( "1351", "12/10/02", "David Tansey",
Origin = "Specification: Missing Requirement",
FixComment = "Added PriceIsValid( ) function" ) ]
public bool PriceIsValid( double tnPrice )
{ return tnPrice > 0.00 && tnPrice < 1000.00 ; }
}
[DefectTrack( "NEW", "12/12/02", "Mike Feltman" ) ]
public class AnotherCustomClass
{
string cMyMessageString ;
public AnotherCustomClass( ){ }
[DefectTrack( "1399", "12/17/02", "David Tansey",
Origin = "Analysis: Missing Requirement" ) ]
public void SetMessage( string lcMessageString )
{ this.cMyMessageString = lcMessageString ; }
}
}
首先,需要確保你可以訪問之前創建的自定義特性,所以需要添加這樣一行代碼,如下:
using MyAttributeClasses ;
到此,你就可以使用自定義特性[DefectTrack]裝飾或點綴你的類聲明和方法了。
SomeCustomPricingClass有兩處地方用到了[DefectTrack]特性。第一個[DefectTrack]特性僅僅使用了三個定位參數,而第二個[DefectTrack]特性還包含了一個命名參數Origin的指定。
[DefectTrack( "1377", "12/15/02", "David Tansey" ) ]
[DefectTrack( "1363", "12/12/02", "Toni Feltman",
Origin = "Coding: Unhandled Exception" ) ]
public class SomeCustomPricingClass
{}
PriceIsValid()方法也使用了自定義特性[DefectTrack],並且指定了兩個命名參數Origin和FixComment。上述代碼包含了[DefectTrack]特性幾個額外的用途,你可以檢測這些特性。
一些讀者可能會感到驚奇,因為對於源代碼修改的信息可以通過使用注釋這種傳統的做法。.Net已經使用工具,通過在注釋裡使用XML塊,把這些信息很好的組織起來。
在源代碼對應的位置,你可以很容易的看到你的注釋。你可以通過文本,分析源代碼裡的注釋,從而處理這些信息,但是這個過程是單調冗長的,並且很容易出現錯誤。.Net提供了工具來處理注釋裡的XML塊,這樣可以消除此類問題。
使用自定義特性可以使你達到同樣的效果,它同樣提供了一種可以有效組織的方法,用於記錄和處理這些信息,並且它還有一個額外的優勢。考慮如下情況,當把源代碼編譯成二進制代碼的時候,你是否已經丟失了代碼的注釋?毫無疑問,注釋已經作為副產品,永遠的從可執行代碼裡移出。相比之下,特性的值已經變成了元數據的一部分,永遠的綁定到一個程序集裡。在沒有源代碼的情況下,你依然可以訪問這些注釋信息。
另外,在源代碼裡允許特性構造一個與當初在設計時值一樣的實例。
獲取自定義特性的值
到此,盡管你已經在類和方法上應用了自定義屬性,但在實戰中你還沒有真正的看到它。不管你是否附加了特性,看起來好像什麼事情也沒有發生。但事實上,事情已經發生了變化,你完全不用理會我的話,你可以用MSIL反編譯工具,打開一個包含使用了自定義特性類型的EXE或者DLL文件。MSIL反編譯工具能使你看到在IL代碼裡你定義的特性和它的值。圖一是使用ILDASM工具,打開本文中例子編譯的EXE文件所看到的。
圖一:C#特性