C#屬性(attribute)
屬性是用來傳遞信息到運行有關像類,方法,結構,枚舉,集等各種元素的行為,在你的程序中聲明的標簽。可以通過使用屬性添加聲明信息的程序。聲明性標記由正方形描繪([])置於它被用於元件上方括號。
屬性用於添加元數據,如編譯器的指令和其他信息,例如注釋,描述,方法和類的程序。 .NET Framework提供了兩種類型的屬性:預先定義的屬性和定製屬性。
指定屬性
指定屬性的語法如下:
[attribute(positional_parameters, name_parameter = value, ...)] element
屬性的名稱和值在方括號內指定的元素該屬性的應用之前。位置參數指定的基本信息和名稱參數指定的可選信息。
預定義的屬性
.NET Framework提供了三個預定義的屬性:
-
AttributeUsage
-
Conditional
-
Obsolete
AttributeUsage:
預先定義的屬性AttributeUsage描述了如何自定義屬性的類可以使用。它指定該屬性可應用的項目類型。
用於指定該屬性的語法如下:
[AttributeUsage( validon, AllowMultiple=allowmultiple, Inherited=inherited )]
這裡,
-
參數validon指明該屬性可以放置在語言元素。它是一個枚舉AttributeTargets的值的組合。默認值是AttributeTargets.All。
-
參數允許多個(可選)提供值這個屬性,一個布爾值的AllowMultiple屬性。如果是true,該屬性為多用途。默認值為false(一次性使用)。
-
繼承的參數(可選)提供值這個屬性,一個布爾值的繼承屬性。如果是true,該屬性由派生類繼承。默認值是false(而不是繼承)。
例如,
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Feild | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
條件
此預定義屬性標誌著一個條件方法的執行依賴於一個指定的預處理標識符。
它引起的方法調用條件編譯,根據所指定的值,如調試或跟蹤。例如,它在調試代碼顯示變量的值。
用於指定該屬性的語法如下:
[Conditional( conditionalSymbol )]
例如,
[Conditional("DEBUG")]
下麵的例子演示了屬性:
#define DEBUG using System; using System.Diagnostics; public class Myclass { [Conditional("DEBUG")] public static void Message(string msg) { Console.WriteLine(msg); } } class Test { static void function1() { Myclass.Message("In Function 1."); function2(); } static void function2() { Myclass.Message("In Function 2."); } public static void Main() { Myclass.Message("In Main function."); function1(); Console.ReadKey(); } }
讓我們編譯和運行上麵的程序,這將產生以下結果:
In Main function In Function 1 In Function 2
廢棄的
這個預定義的屬性標記不應該被使用的程序的實體。它使您能夠告訴編譯器丟棄特定的目標元素。例如,當一個新的方法正在使用中的一個類,仍然要保留舊方法的類,但可以標記,代替舊的方法是通過使用顯示一個消息,這個新方法已經過時。
用於指定該屬性的語法如下:
[Obsolete( message )] [Obsolete( message, iserror )]
這裡,
-
該參數的消息,是一個描述原因的字符串顯示為什麼項目已經過時,用什麼來代替。
-
該參數是iserror,是一個布爾值。如果它的值是true,編譯器應該把使用的項目作為一個錯誤對待。默認值為false(編譯器生成一個警告)。
下麵的程序說明了這一點:
using System; public class MyClass { [Obsolete("Don't use OldMethod, use NewMethod instead", true)] static void OldMethod() { Console.WriteLine("It is the old method"); } static void NewMethod() { Console.WriteLine("It is the new method"); } public static void Main() { OldMethod(); } }
當您嘗試編譯程序,編譯器給出了一個錯誤信息,如下:
Don't use OldMethod, use NewMethod instead
創建自定義屬性
.Net框架允許創建可用於存儲信息的聲明,並可以檢索在運行時間自定義屬性。這個信息可以與根據設計標準和應用的需要的任何目標元素。
創建和使用自定義屬性包括四個步驟:
-
聲明一個自定義屬性
-
構造自定義屬性
-
應用自定義屬性的目標程序元素
-
通過反射訪問屬性
最後一步需要編寫一個簡單的程序來讀取通過元數據來尋找各種符號。元數據是關於用於描述其他數據的數據或信息的數據。這個程序應該使用反射訪問屬性在運行時。為此,反射我們將在下一章中討論。
聲明自定義屬性
一個新的自定義屬性應該是從System.Attribute類派生的。例如,
//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
在上麵的代碼中,我們已經聲明命名的自定義屬性為 DeBugInfo.
構造自定義屬性
讓我們構建名為DeBugInfo的自定義屬性,這將存儲由調試任何程序中獲得的信息。它存儲了以下信息:
-
錯誤的代碼數量
-
發現的錯誤開發人員名稱
-
代碼的最後一次審查的日期
-
存儲開發人員的備注字符串消息
DeBugInfo類將有三個私有屬性存儲前三個信息,公共屬性用於存儲信息。所以這個bug數量,開發者的姓名和審查日期是DeBugInfo類的定位參數;消息將是一個可選或命名參數。
每個屬性必須至少有一個構造函數。參數的位置應通過構造函數來傳遞。下麵的代碼顯示了DeBugInfo類:
//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; } } }
應用自定義屬性
屬性應用於通過立即它的目標之前將其放置:
[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()); } }
在下一章中,我們將檢索使用反射類對象,這些屬性信息。