最近用到了,因此靜下心來找些資料看了一下,終於把這東西搞清楚了。安全
一.什麼是Attribute函數
先看下面的三段代碼:工具
1.自定義Attribute類:VersionAttribute性能
[AttributeUsage(AttributeTargets.Class)] public class VersionAttribute : Attribute { public string Name { get; set; } public string Date { get; set; } public string Describtion { get; set; } }
2.使用自定義Attribute的Class:spa
[Version(Name = "hyddd", Date = "2009-07-20", Describtion = "hyddd's class")] public class MyCode { //... }
3.上面這個Class中的Attribute通常會被如何使用呢?翻譯
class Program { static void Main(string[] args) { var info = typeof(MyCode); var classAttribute = (VersionAttribute)Attribute.GetCustomAttribute(info, typeof(VersionAttribute)); Console.WriteLine(classAttribute.Name); Console.WriteLine(classAttribute.Date); Console.WriteLine(classAttribute.Describtion); } }
示例完畢!上面三段代碼相信已經說明了Attribute大概是一個什麼東西和怎麼去用。對象
二.深刻討論Attribute繼承
1.Attribute的概念定義接口
關於Attribute概念的定義,我直接引用《你必須知道的.NET之特性和屬性》中的一段來講明:事件
MADN的定義爲:公共語言運行時容許添加相似關鍵字的描述聲明,叫作attributes, 它對程序中的元素進行標註,如類型、字段、方法和屬性等。Attributes和Microsoft .NET Framework文件的元數據(metadata)保存在一塊兒,能夠用來向運行時描述你的代碼,或者在程序運行的時候影響應用程序的行爲。
咱們簡單的總結爲:定製特性attribute,本質上是一個類,其爲目標元素提供關聯附加信息,並在運行期以反射的方式來獲取附加信息。
噢,原來Attribute的目的是爲元素提供關聯附加信息。其中,上面第一段代碼中「[AttributeUsage(AttributeTargets.Class)] 」說明了Attribute提供附加信息的元素是Class,因此若是上面第二段的代碼改成:
public class MyCode
{
[Version(Name = "hyddd", Date = "2009-07-20", Describtion = "hyddd's class")]
public void Test() { }
}
會出現編譯錯誤。
2.Attribute做爲編譯指令
Attribute類是在編譯的時候被實例化的,而不是像一般的類那樣在運行時候才實例化。因此在第三段代碼中,你能夠在沒有實例化MyCode對象的狀況下取到MyCode的Attribute信息。因爲Attribute類是在編譯的時候被實例化的,因此你還能夠用外部工具維護這些Attribute信息。
3.Attribute與Property
從中文來講,Attribute和Property的中文都叫「屬性」,很容易讓人混淆。如今的文章,Attribute通常翻譯爲」特性」,而Property稱爲「屬性」。
或許你會問,我用靜態的Property/Field同樣能夠作到在不實例化的時候拿到一些信息,若是這樣的話,Attribute又有什麼存在乎義呢?
1.Property:
Property能夠說是一個面向對象的概念,提供了對私有字段的訪問封裝,在C#中以get和set訪問器方法實現對可讀可寫屬性的操做,提供了安全和靈活的數據訪問封裝。好比:
public class Robot { private string name = ""; //字段:Field public string Name //屬性:Property,對Field進行封裝。 { get { return name; } set { name = value; } } }
2.Attribute:
Attribute的目標是:爲元素提供附加信息。它的做用更相似於註釋。
能夠說,Property/Field和Attribute是兩個徹底不一樣的概念,雖然他們有些時候能作同樣的事,但請記住,他們是從本質上就不一樣的兩個東西。
三.實現本身的Attribute時須要注意的一些問題
1.自定義的Attribute必須直接或者間接繼承System.Attribute。
2.這裏有一個約定:全部自定義的特性名稱都應該有個Attribute後綴。由於當你的Attribute施加到一個程序的元素上的時候,編譯器先查找你的Attribute的定義,若是沒有找到,那麼它就會查找「Attribute名稱"+Attribute的定義。若是都沒有找到,那麼編譯器就報錯。這就是爲何我能夠再上面第一段代碼中,定義一個VersionAttribute,但在第二段代碼中,我使用倒是Version這個Attribute。:>
下面是一些開發自定義Attribute時,可能須要用到的資料:
【1】Attribute能夠關聯的元素包括:
程序集(assembly)、模塊(module)、類型(type)、屬性(property)、事件(event)、字段(field)、方法(method)、參數(param)、返回值(return)。例如:
[assembly: Version(Name = "hyddd", Date = "2009-07-20", Describtion = "hyddd's class")] public class MyCode { //...... }
用指定的前綴來表示特性所應用的目標元素,建議這樣來處理,由於顯式處理能夠消除可能帶來的二義性。
【2】AttributeTargets目標包括:
標記 | 說明 |
All | 能夠對任何應用程序元素應用屬性。 |
Assembly | 能夠對程序集應用屬性。 |
Class | 能夠對類應用屬性。 |
Constructor | 能夠對構造函數應用屬性。 |
Delegate | 能夠對委託應用屬性。 |
Enum | 能夠對枚舉應用屬性。 |
Event | 能夠對事件應用屬性。 |
Field | 能夠對字段應用屬性。 |
GenericParameter | 能夠對泛型參數應用屬性。 |
Interface | 能夠對接口應用屬性。 |
Method | 能夠對方法應用屬性。 |
Module | Module 指的是可移植的可執行文件(.dll 或 .exe),而非 Visual Basic 標準模塊。 |
Parameter | 能夠對參數應用屬性。 |
Property | 能夠對屬性 (Property) 應用屬性 (Attribute)。 |
ReturnValue | 能夠對返回值應用屬性。 |
Struct | 能夠對結構應用屬性,即值類型。 |
【3】AttributeUsageAttribute中的3個屬性(Property)說明:
屬性名 | 說明 |
ValidOn | 該定位參數指定可在其上放置所指示的屬性 (Attribute) 的程序元素。AttributeTargets 枚舉數中列出了可在其上放置屬性 (Attribute) 的全部可能元素的集合。可經過按位「或」運算組合多個 AttributeTargets 值,以獲取所需的有效程序元素組合。 |
AllowMultiple | 該命名參數指定可否爲給定的程序元素屢次指定所指示的屬性。 |
Inherited | 該命名參數指定所指示的屬性可否由派生類和重寫成員繼承。 |