黑馬程序員-.NET基礎之特性

------- Windows Phone 7手機開發.Net培訓、期待與您交流! -------

 

一、特性概述

C#語言可以創建直接或間接派生於抽象類System.Attribute的類,稱之爲特性(Attribute)類。
一個關於特性類的聲明定義一種新特性,特性可以被放置在其他聲明上,即附加到各種程序實體(包括類型、方法、屬性等),以添加元數據信息,如編譯器指令或數據描述。特性主要爲編譯器提供額外的信息,編譯器可以通過這些附加特性,自動生成相應的代碼,從而實現特定的功能。程序代碼也可以通過反射技術,在運行時環境中檢索這些特性信息,以實現特定的操作。
C#語言包括下列2種形式的特性:
公共語言運行庫(CLR)中預定義的特性
自定義特性,用於向代碼中添加附加信息,該信息能夠以編程方式檢索
特性類可以具有定位參數(positional parameter)和命名參數(named parameter)列表

 

二、特性的使用

    將特性附加到程序實體的語法爲:將括在方括號中的特性名置於其適用的實體聲明之前。例如,C#外部方法的聲明需要通過DllImport 特性以引用由DLL(動態鏈接庫)實現的外部函數。根據約定,所有特性類都以單詞“Attribute”結束,以區分於其它類。但是,在代碼中,可以省略特性後綴“Attribute”

 

三、預定義通用特性類

    ConditionalAttribute類,ObsoleteAttribute類,AttributeUsageAttribute類,全局特性。下面給出預定義通用特性類ConditionalAttribute使用示例。

using System;
using System.Diagnostics;
namespace CSharpPractice.Attribute
{
    public class Trace
    {
        [Conditional("DEBUG")]
        public static void Msg(string msg)
        {
            Console.WriteLine(msg);
        }
        [Conditional("DEBUG"), Conditional("TRACE")]
        public static void Method2()
        {
            Console.WriteLine("DEBUG or TRACE is defined");
        }
    }
    public class ProgramClass
    {
        static void Main()
        {
            Trace.Msg("Now in Main...");
            Trace.Method2();
            Console.WriteLine("Main Done.");
            Console.ReadLine();
        }
    }
}

 

 

四、自定義特性類

    通過直接或間接地從System.Attribute類派生,可以創建自定義特性類。特性類直接或間接地從 Attribute 派生,有助於方便快捷地在元數據中標識特性定義。
特性類的聲明遵循下列規則:
派生類的類名一般採用XXXAttribute的命名規範,類名就是特性名。
構造函數的參數是自定義特性的定位參數。
任何公共讀寫字段或屬性都是命名參數。
使用AttributeUsage特性指定特性類的限制條件

namespace CSharpPractice.Attribute
{

    [System.AttributeUsage(System.AttributeTargets.Class |
                           System.AttributeTargets.Struct,
                           AllowMultiple = true)  // 允許單個實體應用多次該屬性
    ]
    public class AuthorAttribute : System.Attribute
    {
        private string name;
        public double version;
        public AuthorAttribute(string name)
        {
            this.name = name;
            version = 1.0;
        }
    }
    [Author("H. Ackerman", version = 1.1)]
    [Author("M. Knott", version = 1.2)]
    class SampleClass
    {    // H. Ackerman's code goes here...
        // M. Knott's code goes here...
        public static void Main()
        {
            System.Console.WriteLine("Hello!");
            System.Console.ReadLine();
        }
    }
}


 

五、使用反射訪問特性

    C#通過反射技術來檢索用自定義特性定義的信息。首先通過GetType方法或者typeof關鍵字來獲取類型;然後通過GetCustomAttributes方法獲取所應用的自定義特性的對象數組;最後通過自定義特性的對象數組進行相應的操作處理。下面給出通過反射技術檢索用自定義特性定義的信息示例。

namespace CSharpPractice.Attribute
{
    [System.AttributeUsage(System.AttributeTargets.Class |
                         System.AttributeTargets.Struct,
                         AllowMultiple = true)  // 允許單個實體應用多次該特性
    ]
    public class AuthorAttribute : System.Attribute
    {
        string name;           // 作者姓名
        public double version;   // 版本
        public AuthorAttribute(string name)
        {
            this.name = name;   // 設置作者姓名
            version = 1.0;      // 默認版本值
        }
        public string GetName()
        {   // 獲取作者姓名信息
            return name;
        }
    }
    [Author("H. Ackerman")]
    class FirstClass
    {
        // ...
    }
    // 無作者特性
    class SecondClass
    {
        // ...
    }
    [Author("H. Ackerman"), Author("M. Knott", version = 2.0)]
    class ThirdClass
    {
        // ...
    }
    class TestAuthorAttribute
    {
        static void Main()
        {  // 打印3位作者的信息
            PrintAuthorInfo(typeof(FirstClass));
            PrintAuthorInfo(typeof(SecondClass));
            PrintAuthorInfo(typeof(ThirdClass));
            System.Console.ReadLine();
        }
        private static void PrintAuthorInfo(System.Type t)
        {
            System.Console.WriteLine("{0} 的作者信息:", t);
            System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);  // 反射技術
            foreach (System.Attribute attr in attrs)
            {
                if (attr is Author)
                {
                    Author a = (Author)attr;
                    System.Console.WriteLine("   {0}, 版本 {1:f}", a.GetName(), a.version);
                }
            }
            System.Console.ReadLine();
        }
    }
}

 

------- Windows Phone 7手機開發.Net培訓、期待與您交流! -------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章