Attribute的基本概念

來源:互聯網
上載者:User
文章目錄
  • Attribute作為編譯器的指令
  • Attribute類
  • AttributeUsage 的使用例子:

Attribute的基本概念

經常有朋友問,Attribute是什嗎?它有什麼用?好像沒有這個東東程式也能運行。實際上在.Net中,Attribute是一個非常重要的組成部分,為了協助大家理解和掌握Attribute,以及它的使用方法,特地收集了幾個Attribute使用的例子,提供給大家參考。

在具體的示範之前,我想先大致介紹一下Attribute。我們知道在類的成員中有property成員,二者在中文中都做屬性解釋,那麼它們到底是不是同一個東西呢?從代碼上看,明顯不同,首先就是它們的在代碼中的位置不同,其次就是寫法不同(Attribute必須寫在一對方括符中)。

什麼是Atrribute

首先,我們肯定Attribute是一個類,下面是msdn文檔對它的描述:
通用語言執行平台允許你添加類似關鍵字的描述聲明,叫做 attributes, 它對程式中的元素進行標註,如類型、欄位、方法和屬性等。Attributes和Microsoft .NET Framework檔案的中繼資料儲存在一起,可以用來向運行時描述你的代碼,或者在程式啟動並執行時候影響應用程式的行為。

在.NET中,Attribute被用來處理多種問題,比如序列化、程式的安全特徵、防止即時編譯器對程式碼進行最佳化從而代碼容易調試等等。下面,我們先來看幾個在.NET中標準的屬性的使用,稍後我們再回過頭來討論Attribute這個類本身。(文中的代碼使用C#編寫,但同樣適用所有基於.NET的所有語言)

Attribute作為編譯器的指令

在C#中存在著一定數量的編譯器指令,如:#define DEBUG, #undefine DEBUG, #if等。這些指令專屬於C#,而且在數量上是固定的。而Attribute用作編譯器指令則不受數量限制。比如下面的三個Attribute:

  • Conditional:起條件編譯的作用,只有滿足條件,才允許編譯器對它的代碼進行編譯。一般在程式調試的時候使用。
  • DllImport:用來標記非.NET的函數,表明該方法在一個外部的DLL中定義。
  • Obsolete:這個屬性用來標記當前的方法已經被廢棄,不再使用了。

下面的代碼示範了上述三個屬性的使用:

 #define DEBUG //這裡定義條件    using System;using System.Runtime.InteropServices;using System.Diagnostics;    namespace AttributeDemo{   class MainProgramClass   {       [DllImport("User32.dll")]      public static extern int MessageBox(int hParent, string Message, string Caption, int Type);           static void Main(string[] args)      {         DisplayRunningMessage();         DisplayDebugMessage();              MessageBox(0,"Hello","Message",0);              Console.ReadLine();      }           [Conditional("DEBUG")]      private static void DisplayRunningMessage()      {         Console.WriteLine("開始運行Main子程式。目前時間是"+DateTime.Now);      }        [Conditional("DEBUG")]      [Obsolete]      private static void DisplayDebugMessage()      {         Console.WriteLine("開始Main子程式");      }   }}  

如果在一個程式元素前面聲明一個Attribute,那麼就表示這個Attribute被施加到該元素上,前面的代碼,[DllImport]施加到MessageBox函數上, [Conditional]施加到DisplayRuntimeMessage方法和DisplayDebugMessage方法,[Obsolete] 施加到DisplayDebugMessage方法上。

根據上面涉及到的三個Attribute的說明,我們可以猜到程式啟動並執行時候產生的輸出:DllImport Attribute表明了MessageBox是User32.DLL中的函數,這樣我們就可以像內部方法一樣調用這個函數。

重要的一點就是Attribute就是一個類,所以DllImport也是一個類,Attribute類是在編譯的時候被執行個體化的,而不是像通常的類那樣在運行時候才執行個體化。Attribute執行個體化的時候根據該Attribute類的設計可以帶參數,也可以不帶參數,比如DllImport就帶有"User32.dll"的參數。Conditional對滿足參數的定義條件的代碼進行編譯,如果沒有定義DEBUG,那麼該方法將不被編譯,讀者可以把#define DEBUG一行注釋掉看看輸出的結果(release版本,在Debug版本中Conditional的debug總是成立的)。Obsolete表明了 DispalyDebugMessage方法已經過時了,它有一個更好的方法來代替它,當我們的程式調用一個聲明了Obsolete的方法時,那麼編譯器會給出資訊,Obsolete還有其他兩個重載的版本。大家可以參考msdn中關於的ObsoleteAttribute 類的描述。

Attribute類

除了.NET提供的那些Attribute衍生類別之外,我們可以自訂我們自己的Attribute,所有自訂的Attribute必須從 Attribute類派生。現在我們來看一下Attribute 類的細節:

protected Attribute(): 保護的構造器,只能被Attribute的衍生類別調用。

三個靜態方法:

static Attribute GetCustomAttribute():這個方法有8種重載的版本,它被用來取出施加在類成員上指定類型的Attribute。

static Attribute[] GetCustomAttributes(): 這個方法有16種重載版本,用來取出施加在類成員上指定類型的Attribute數組。

static bool IsDefined():由八種重載版本,看是否指定類型的定製attribute被施加到類的成員上面。

執行個體方法:

bool IsDefaultAttribute(): 如果Attribute的值是預設的值,那麼返回true。

bool Match():表明這個Attribute執行個體是否等於一個指定的對象。

公用屬性: TypeId: 得到一個唯一的標識,這個標識被用來區分同一個Attribute的不同執行個體。

我們簡單地介紹了Attribute類的方法和屬性,還有一些是從object繼承來的。這裡就不列出來了。

下面介紹如何自訂一個Attribute: 自訂一個Attribute並不需要特別的知識,其實就和編寫一個類差不多。自訂的Attribute必須直接或者間接地從Attribute這個類派生,如:

public MyCustomAttribute : Attribute { ... }

這裡需要指出的是Attribute的命名規範,也就是你的Attribute的類名+"Attribute",當你的Attribute施加到一個程式的元素上的時候,編譯器先尋找你的Attribute的定義,如果沒有找到,那麼它就會尋找“Attribute名稱"+Attribute的定義。如果都沒有找到,那麼編譯器就報錯。

對於一個自訂的Attribute,你可以通過AttributeUsage的Attribute來限定你的Attribute 所施加的元素的類型。代碼形式如下: [AttriubteUsage(參數設定)] public 自訂Attribute : Attribute { ... }

非常有意思的是,AttributeUsage本身也是一個Attribute,這是專門施加在Attribute類的Attribute. AttributeUsage自然也是從Attribute派生,它有一個帶參數的構造器,這個參數是AttributeTargets的枚舉類型。下面是AttributeTargets 的定義:

public enum AttributeTargets{   All=16383,   Assembly=1,   Module=2,   Class=4,   Struct=8,   Enum=16,   Constructor=32,   Method=64,   Property=128,   Field=256,   Event=512,   Interface=1024,   Parameter=2048,   Delegate=4096,   ReturnValue=8192}                   

作為參數的AttributeTarges的值允許通過“或”操作來進行多個值得組合,如果你沒有指定參數,那麼預設參數就是All 。 AttributeUsage除了繼承Attribute 的方法和屬性之外,還定義了以下三個屬性:

AllowMultiple: 讀取或者設定這個屬性,表示是否可以對一個程式元素施加多個Attribute 。

Inherited:讀取或者設定這個屬性,表示是否施加的Attribute 可以被衍生類別繼承或者重載。

ValidOn: 讀取或者設定這個屬性,指明Attribute 可以被施加的元素的類型。

AttributeUsage 的使用例子:
using System; namespace AttTargsCS {    // 該Attribute只對類有效.    [AttributeUsage(AttributeTargets.Class)]   public class ClassTargetAttribute : Attribute    {     }    // 該Attribute只對方法有效.    [AttributeUsage(AttributeTargets.Method)]   public class MethodTargetAttribute : Attribute    {     }    // 該Attribute只對構造器有效。   [AttributeUsage(AttributeTargets.Constructor)]   public class ConstructorTargetAttribute : Attribute    {     }    // 該Attribute只對欄位有效.    [AttributeUsage(AttributeTargets.Field)]   public class FieldTargetAttribute : Attribute   {   }      // 該Attribute對類或者方法有效(組合).   [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)]   public class ClassMethodTargetAttribute : Attribute   {    }    // 該Attribute對所有的元素有效.   [AttributeUsage(AttributeTargets.All)]   public class AllTargetsAttribute : Attribute   {    }    //上面定義的Attribute施加到程式元素上的用法   [ClassTarget]  //施加到類   [ClassMethodTarget]//施加到類   [AllTargets] //施加到類   public class TestClassAttribute   {       [ConstructorTarget] //施加到構造器      [AllTargets] //施加到構造器      TestClassAttribute()      {        }       [MethodTarget] //施加到方法      [ClassMethodTarget] //施加到方法      [AllTargets] //施加到方法      public void Method1()      {      }           [FieldTarget] //施加到欄位      [AllTargets] //施加到欄位      public int myInt;       static void Main(string[] args)      {       }    }}           

 

至此,我們介紹了有關Attribute類和它們的代碼格式。你一定想知道到底如何在你的應用程式中使用Attribute,如果僅僅是前面介紹的內容,還是不足以說明Attribute有什麼實用價值的話,那麼從後面的章節開始我們將介紹幾個Attribute的不同用法,相信你一定會對 Attribute有一個新的瞭解。(待續)

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.