鍍金池/ 教程/ C#/ 特性
循環(huán)
正則表達(dá)式
概述
委托
多態(tài)性
字符串
繼承
結(jié)構(gòu)體
集合
變量
不安全代碼
判斷
反射
異常處理
可空類型
方法
數(shù)據(jù)類型
命名空間
文件 I/O
類型轉(zhuǎn)換
屬性
程序結(jié)構(gòu)
事件
接口
預(yù)處理指令
運(yùn)算符
多線程
匿名方法
索引器
泛型
封裝
常量和文字
基本語(yǔ)法
特性
數(shù)組
環(huán)境配置
運(yùn)算符重載
枚舉

特性

特性(Attribute)是用于在運(yùn)行時(shí)傳遞程序中各種元素(比如類、方法、結(jié)構(gòu)、枚舉、組件等)的行為信息的聲明性標(biāo)簽。您可以通過(guò)使用特性向程序添加聲明性信息。一個(gè)聲明性標(biāo)簽是通過(guò)放置在它所應(yīng)用的元素前面的方括號(hào)([ ])來(lái)描述的。

特性(Attribute)用于添加元數(shù)據(jù),如編譯器指令和注釋、描述、方法、類等其他信息。.Net 框架提供了兩種類型的特性:預(yù)定義特性和自定義特性。

列舉特性

列舉特性的語(yǔ)法如下:

    [attribute(positional_parameters, name_parameter = value, ...)]
    element

特性的名稱和值都是在方括號(hào)內(nèi)規(guī)定的,放在這個(gè)特性應(yīng)用的元素之前。表示位置的參數(shù)規(guī)定出特性的基本信息,名稱參數(shù)規(guī)定了可選擇的信息。

預(yù)定義特性

.Net Framework 提供了三種預(yù)定義的特性:

  • AttributeUsage
  • Conditional
  • Obsolete

AttributeUsage

該特性描述了用戶定義的特性類是如何使用的。它規(guī)定了某個(gè)特性應(yīng)用的項(xiàng)目類型。

規(guī)定這種特性的語(yǔ)法如下:

    [AttributeUsage(
        validon,
        AllowMultiple=allowmultiple,
        Inherited=inherited
    )]

其中,

  • 參數(shù) validon 規(guī)定特性了能承載特性的語(yǔ)言元素。它是枚舉器 AttributeTargets 的值的組合。默認(rèn)值是 AttributeTargets.All。
  • 參數(shù) allowmultiple(可選的)為該特性的 AllowMultiple 屬性提供了一個(gè)布爾值。如果為 true,則該特性是多用的。默認(rèn)值是 false(單用的)。
  • 參數(shù) inherited(可選的)為該特性的 Inherited 屬性提供一個(gè)布爾值。如果為 true,則該特性可被派生類繼承。默認(rèn)值是 false(不可繼承)。

例如:

    [AttributeUsage(AttributeTargets.Class |
    AttributeTargets.Constructor |
    AttributeTargets.Field |
    AttributeTargets.Method |
    AttributeTargets.Property, 
    AllowMultiple = true)]

Conditional

這個(gè)預(yù)定義特性標(biāo)記了一個(gè)條件方法,其執(zhí)行依賴于特定的預(yù)處理標(biāo)識(shí)符。

它會(huì)引起方法調(diào)用的條件編譯,取決于指定的值,比如 Debug 或 Trace。例如,當(dāng)調(diào)試代碼時(shí)顯示變量的值。

規(guī)定該特性的語(yǔ)法如下:

    [Conditional(
        conditionalSymbol
    )]

例如:

    [Conditional("DEBUG")]

下面的實(shí)例演示了該特性:

    #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();
        }
    }

編譯執(zhí)行上述代碼,得到如下結(jié)果:

    In Main function
    In Function 1   
    In Function 2

Obsolete

這個(gè)預(yù)定義特性標(biāo)記了不應(yīng)被使用的程序?qū)嶓w。它可以讓您通知編譯器丟棄某個(gè)特定的目標(biāo)元素。例如,當(dāng)一個(gè)新方法被用在一個(gè)類中,但是您仍然想要保持類中的舊方法,您可以通過(guò)顯示一個(gè)應(yīng)該使用新方法,而不是舊方法的消息,來(lái)把它標(biāo)記為 obsolete(過(guò)時(shí)的)。

規(guī)定該特性的語(yǔ)法如下:

    [Obsolete(
        message
    )]
    [Obsolete(
        message,
        iserror
    )]

其中,

  • 參數(shù) message,是一個(gè)字符串,描述項(xiàng)目為什么過(guò)時(shí)的原因以及該替代使用什么。
  • 參數(shù) iserror,是一個(gè)布爾值。如果該值為 true,編譯器應(yīng)把該項(xiàng)目的使用當(dāng)作一個(gè)錯(cuò)誤。默認(rèn)值是 false(編譯器生成一個(gè)警告)。

下面的實(shí)例演示了該特性:

    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();
        }
    }

當(dāng)你執(zhí)行這個(gè)程序時(shí),編譯器會(huì)提示如下的錯(cuò)誤:

    Don't use OldMethod, use NewMethod instead

創(chuàng)建自定義的特性

.Net 框架允許創(chuàng)建自定義特性,用于存儲(chǔ)聲明性的信息,且可在運(yùn)行時(shí)被檢索。該信息根據(jù)設(shè)計(jì)標(biāo)準(zhǔn)和應(yīng)用程序需要,可與任何目標(biāo)元素相關(guān)。

創(chuàng)建并使用自定義特性包含四個(gè)步驟:

  • 聲明自定義特性
  • 構(gòu)建自定義特性
  • 在目標(biāo)程序元素上應(yīng)用自定義特性
  • 通過(guò)反射訪問(wèn)特性

最后一個(gè)步驟包含編寫一個(gè)簡(jiǎn)單的程序來(lái)讀取元數(shù)據(jù)以便查找各種符號(hào)。元數(shù)據(jù)是用于描述其他數(shù)據(jù)的數(shù)據(jù)和信息。該程序應(yīng)使用反射來(lái)在運(yùn)行時(shí)訪問(wèn)特性。我們將在下一章詳細(xì)討論這點(diǎn)。

聲明自定義特性

一個(gè)新的自定義特性應(yīng)派生自 System.Attribute 類。例如:

    //一個(gè)自定義的特性BugFix被分配給類和類的成員
    [AttributeUsage(AttributeTargets.Class |
    AttributeTargets.Constructor |
    AttributeTargets.Field |
    AttributeTargets.Method |
    AttributeTargets.Property,
    AllowMultiple = true)]

    public class DeBugInfo : System.Attribute

在上面的代碼中,我們已經(jīng)聲明了一個(gè)名為 DeBugInfo 的自定義特性。

構(gòu)建自定義特性

讓我們構(gòu)建一個(gè)名為 DeBugInfo 的自定義特性,該特性將存儲(chǔ)調(diào)試程序獲得的信息。它存儲(chǔ)下面的信息:

  • bug 的代碼編號(hào)
  • 辨認(rèn)該 bug 的開發(fā)人員名字
  • 最后一次審查該代碼的日期
  • 一個(gè)存儲(chǔ)了開發(fā)人員標(biāo)記的字符串消息

我們的 DeBugInfo 類將帶有三個(gè)用于存儲(chǔ)前三個(gè)信息的私有屬性(property)和一個(gè)用于存儲(chǔ)消息的公有屬性(property)。所以 bug 編號(hào)、開發(fā)人員名字和審查日期將是 DeBugInfo 類的必需的定位( positional)參數(shù),消息將是一個(gè)可選的命名(named)參數(shù)。

每個(gè)特性必須至少有一個(gè)構(gòu)造函數(shù)。必需的定位( positional)參數(shù)應(yīng)通過(guò)構(gòu)造函數(shù)傳遞。下面的代碼演示了 DeBugInfo 類:

    //一個(gè)自定義的特性BugFix被分配給類和類的成員
    [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;
            }
        }   
    }

應(yīng)用自定義特性

通過(guò)將特性放置在目標(biāo)之前來(lái)使用它:

    [DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")]
    [DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")]
    class Rectangle
    {
        //成員變量
        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());
        }
    }

在下一章節(jié)中,我們會(huì)介紹如何使用 Reflection 類來(lái)檢索特性信息。

上一篇:屬性下一篇:文件 I/O