程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 深入淺出Attribute (上)——Attribute初體驗

深入淺出Attribute (上)——Attribute初體驗

編輯:關於C語言

小序:

         注意:本次小序頗長而且沒什麼正事兒,建議大家直接跳到正文,以免浪費寶貴時間:)          積水潭橋旁的物美大賣場有兩層——B1B2B1賣電器和日用品概括起來說就是那些不能吃的——貓糧除外),B2是賣食品的,又分為兩個區,南區是賣零食的,北區是賣蔬菜水果生肉熟肉的。以前轉的最多的是南區,購物車裡大包小包一堆零食還要再抱上兩大桶可樂,衣著整潔的時候偶爾還假裝斯文給打扮入時的小MM讓個路、擠個眉弄個眼兒什麼的;現在基本上只在北區轉了,購物車裡全是折價蔬菜大米油鹽,每天都是褲衩背心、趿拉著拖鞋,經常是跟退休的大媽們混戰在一起扒拉架豆角或者擗菜幫……            ~~~逛超市最麻煩的倒不是買東西,而是排大長隊付款——尤其是周末:p 不過,本周末晚上我可是碰見一猛人,PLMM。她先是從北區後場啟動,嘁哩喀喳裝了一堆菜到稱重處過秤,然後靈活地繞過干貨區,然後在到達南北區的中線的時候來了個急停。左顧右盼幾秒鐘後,“啪、啪”裝了兩大包FB面之後便突然啟動殺入了零食林立的南區中場——只見她矯健的身影在零食區的貨架間穿插自如、大搞S形機動,桑巴之態如入無人之境,幾乎overload的購物車在她腳下,不,是手中!左盤右帶、就像魔術師手中的道具一樣靈活。她打開一張紙,大概是要買的東西,從上到下掃描一遍後自信地點了下頭——看來是要買的東西已經買齊了,然後瞇起眼睛、遠遠地望了一眼收銀台,臉上略過一絲不易察覺的、邪邪的笑……   看!她加速了,加速了!!她已經沖過了飲料區,兩個顧客橫在過道出口、封住了她前進的道路。只見她又是一個急停,把車以90度角向左一推,然後再以90度角向右一轉——這是多麼流暢的普加喬夫眼鏡蛇機動!兩個顧客還沒有反應過來,她已經殺出了飲料區,直奔收銀台……   離收銀台不足十碼了!眼看就有兩個顧客要卡在她前面交費了!怎麼辦!怎麼辦?! 她先是利用自己的速度優勢殺到較近的一個顧客身旁,輕挑車頭,打算用假動作騙過這名顧客,讓這名顧客迫於壓力進入另一付費通道。看!她成功了!!而這時,另一名顧客馬上就要進入交費通道了——剎那間,她做出了另人不可思議的動作!她先是把車往左一帶,然後又往右一撥,雙手突然發力腳下同時加速——人車分過!人車分過!!!哇噻!!她又成功了!!此時,她面前只有收銀員了!!面對收銀員她絲毫沒有遲疑、沒有猶豫、沒有任何放慢速度的意思——偉大的意大利左後衛!!!勝利是屬於你的!!!   ~~~~~~~~~~~~~~ 在警報響起的同時,收銀員穩穩地將車抱入懷中! 沖撞收銀員!超市管理員跑過來了,一邊跑一邊~~~好像是在掏牌兒~~~讓我們看看他掏的是什麼牌兒……哇哦!紅牌,是紅牌!! 兩名保安走過來,准備把PLMM架出場外。超市管理員來到收銀員旁邊,察看收銀員有沒有受傷。 怎麼回事?!場上一陣騷亂!一名保安倒在了地上,痛苦地捂著胸口在地上打滾!這到底是怎麼回事?讓我們看一下超市監控錄像的慢動作回放……保安先是拉了一下MMT Shirt,被MM用手撥開,走了兩步之後,MM突然沖回來用頭狠狠地頂在保安的胸口!保安凌空翻轉,重重摔在地上!——God!這到底是怎麼回事?!保安到底對MM做了什麼,或者是說了什麼,以致MM出此狠招?! ……

正文:

         什麼是AttributeAttribute是干什麼使的?AttributeProperty到底有什麼區別?…… 長久以來,這些問題一直困擾著並不怎麼廣大的C#初學者。原因大概有兩個,一是Attribute平時不怎麼常用沒用慣怎麼可能常用嗎!)二是這個家伙不太好翻譯——它與Property這個詞意義相近,都有“屬性”這個詞條而且在HTML語言中,Attribute也的確與C#面向對象概念中的Property意思一致),因此很多譯者,特別是C#剛剛出來那陣子,拿捏不好應該怎麼翻譯,搞的C#初學者一遇到“屬性”就發懵、一遇到“Attribute”就發怵。現在情況還算比較明朗了,Attribute一般譯作“特性”,Property仍然譯為“屬性”。          今天,先讓我們來學習一下到底什麼是Attribute並體驗一下Attribute的威力,然後讓我們徹底澄清AttributeProperty之間的區別。

什麼是Attribute:

         大多數書籍都喜歡講——“Attribute是一種可由用戶自由定義的修飾符Modifier),可以用來修飾各種需要被修飾的目標”——如此晦澀的言辭,怎麼可能讓新手一下子明白呢?不過,等你看完這篇文章、成為“老手”之後,你會發現這句話說得還是挺有道理的。)況且,修飾符比如privatepublicstaticrefout等等)都是C#語言本身的關鍵字,而Attribute看起來又與語言本身不著邊際。GodAttribute到底是個什麼東東呢? 其實特別簡單——Attribute就是一種“附著物”——就像牡蛎吸附在船底或礁石上一樣。這些附著物的作用是為它們的附著體追加上一些額外的信息這些信息就保存在附著物的體內)——比如“這個類是我寫的”或者“這個函數以前出過問題”等等。          你可能會問:這跟注釋有什麼區別呢?          當然有區別啦!注釋是對程序源代碼的一種說明,主要目的是給人看的,在程序被編譯的時候會被編譯器所丟棄,因此,它絲毫不會影響到程序的執行。而Attribute是程序代碼的一部分,不但不會被編譯器丟棄,而且還會被編譯器編譯進程序集Assembly)的元數據Metadata)裡,在程序運行的時候,你隨時可以從元數據裡提取出這些附加信息來決策程序的運行。          口說無憑,舉個例子你馬上就會明白了——讓我們來考慮這樣一種情況:          有一個類,由兩個程序員——小張和小李——共同維護。這個類是在項目中起一個“工具包”Utilities)的作用就像.NET Framework中的Math類一樣),裡面含了幾十個靜態方法也就是用static修飾過的函數啦)。這些靜態方法中,一半是小張寫的、一半是小李寫的;在項目的測試中,還有一些靜態方法曾經出過bug,當然後來又被修正過了。這樣,我們就可以把這些方面劃分成這樣幾類:            我們分類的目的主要是在測試的時候可以按不同的類別進行測試、獲取不同的效果——比如統計兩個人的工作量或者對曾經出過bug的方法進行回歸測試。 如果不使用Attribute,為了區分這四類靜態方法,我們有兩種方法: 1.         把這些信息體現在方法的名稱中,看起來就像這樣——                    //...                    public static void Li_Buged_Method_1(double arg1, double arg2) { /*...*/}                    public static void Li_NoBug_Method_2(double arg1, double arg2) { /*...*/}                    public static void Zhang_Buged_Method_3(double arg1, double arg2) { /*...*/}                    public static void Zhang_NoBug_Method_4(double arg1, double arg2) { /*...*/}          //...                    很顯然,這樣是行不通的,因為這樣會在方法命名中遺留很多與程序邏輯本身無關的“垃圾信息”。舉個極端點兒的例子:如果小張和小李調走了,由小趙和小孫接手他們的工作,後來小趙和小孫也調走了,由小劉和小王接手維護工作……舊方法的名字不敢改,新方法的名字要用新姓氏命名,時間一長,這個類就跟《百家姓》沒什麼區別了:p 2.         另一種方法是為每個方法加注釋,看起來會是這樣——                    //...                    public static void Method_1(double arg1, double arg2) { /*...*/}          // Created By Li, Buged                    public static void Method_2(double arg1, double arg2) { /*...*/}         // Created By Li, NoBug                    public static void Method_3(double arg1, double arg2) { /*...*/}          // Created By Zhang, Buged                    public static void Method_4(double arg1, double arg2) { /*...*/}          // Created By Zhang, NoBug          //...                    這樣做的好處是清除了代碼中的“垃圾信息”,但情況並沒有好到哪兒去。為了統計程序員的工作量,你還得一邊看注釋一邊計數,為了把出過bug和沒出過bug的方法分開跑,你要在執行的時候不停地把這個方法注釋掉在調用前加//,取消它的執行)、為那個方法取消注釋……如果是幾十個方法還好辦,如果是幾千個呢?別不相信,我在MSN測試組裡呆著的時候,一組方法就有一千四百多個呢!)之所以出現這個問題,根本原因是注釋會被編譯器拋棄,因此在執行期注釋絲毫幫不上我們的忙。          難道我們沒有別的辦法了嗎?峰回路轉,Attribute登場!

Attribute范例

請編譯運行下面這個程序:   //====水之真谛====//
//上善若水,潤物無聲//
/* [url]http://blog.csdn.net/FantasiaX[/url]  */

//#define NOBUG
#define BUGED  // C#的宏定義必須出現在所有代碼之前。當前我們只讓BUGED宏有效。
//#define LI
//#define ZHANG

using System;
using System.Diagnostics; // 注意:這是為了使用包含在此名稱空間中的ConditionalAttribute特性

namespace AttributeSample
{
         class ToolKit
         {
                   [ConditionalAttribute("LI")]                                           // Attribute名稱的長記法
                   [ConditionalAttribute("BUGED")]
                   public static void Method1() { Console.WriteLine("Created By Li, Buged."); }

                   [ConditionalAttribute("LI")]
                   [ConditionalAttribute("NOBUG")]
                   public static void Method2() { Console.WriteLine("Created By Li, NoBug."); }

                   [Conditional("ZHANG")]                                               // Attribute名稱的短記法
                   [Conditional("BUGED")]
                   public static void Method3() { Console.WriteLine("Created By Zhang, Buged."); }

                   [Conditional("ZHANG")]
                   [Conditional("NOBUG")]
                   public static void Method4() { Console.WriteLine("Created By Zhang, NoBug."); }
         }
         class Program
         {
                   static void Main(string[] args)
                   {
                            // 雖然方法都被調用了,但只有符合條件的才會被執行。
                            ToolKit.Method1();
                            ToolKit.Method2();
                            ToolKit.Method3();
                            ToolKit.Method4();
                   }
         }
}

執行結果:  
實例分析: 1.         在本例中,我們使用了ConditionalAttribute這個Attribute,它被包含在System.Diagnostics名稱空間中。顯然,它多半時間是用來做程序調試與診斷的。 2.         ConditionalAttribute相關的是一組C#宏,它們看起來與C語言的宏別無二致,位置必需出現在所有C#代碼之前。顧名思義,ConditionalAttribute是用來判斷條件的,而這組宏就是將被ConditionalAttribute所判斷的條件。凡被ConditionalAttribute“附著”了的方法,只有滿足了條件才會執行。 3.         就像船底上可以附著很多牡蛎一樣,一個方法上也可以附著多個ConditionalAttribute的實例。把Attribute附著在目標上的書寫格式很簡單——用方括號把Attribute一括就行了,後面緊接著寫Attribute的附著體就行了。當多個Attribute附著在同一個目標上時,把這些Attribute的方括號一個挨一個地書寫就行了或者是在一對方括號中書寫多個Attribute),而且不必在乎它們的順序。 4.         在使用Attribute的時候,有“長記法”和“短記法”兩種,請君自便J 由上面的第3和第4條我們可以推出,以下四種Attribute的使用方式是完全等價的:                      [ConditionalAttribute("LI")]                        // 長記法                    [ConditionalAttribute("NOBUG")]          public static void Method2() { Console.WriteLine("Created By Li, NoBug."); }                      [Conditional("LI")]                                        // 短記法                    [Conditional("NOBUG")]          public static void Method2() { Console.WriteLine("Created By Li, NoBug."); }                      [Conditional("NOBUG")]                           // 換序                    [Conditional("LI")]          public static void Method2() { Console.WriteLine("Created By Li, NoBug."); }                      [Conditional("NOBUG"), Conditional("LI")]                      // 單括號疊加                    public static void Method2() { Console.WriteLine("Created By Li, NoBug."); }            當我們對Attribute的用途有所了解後,我們就可以向Attribute的本質進發了!    TO BE CONTINUE 請關注:
  • 《深入淺出Attribute》中)——Attribute的本質
  • 《深入淺出Attribute》下)——Attribute V.S. Property
法律聲明:本文章受到知識產權法保護,任何單位或個人若需要轉載此文,必需保證文章的完整性未經作者許可的任何刪節或改動將視為侵權行為)。若您需要轉載,請務必注明文章出處為BKJIA以保障網站的權益;請務必注明文章作者為劉鐵猛[url]http://liutiemeng.blog.51cto.com[/url]),並向[email protected]發送郵件,標明文章位置及用途。轉載時請將此法律聲明一並轉載,謝謝!

本文出自 “上善若水 潤物無聲” 博客,請務必保留此出處http://liutiemeng.blog.51cto.com/120361/29201

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved