前言:上篇 C#基礎系列——反射筆記 總結了下反射得基礎用法,這章我們來看看C#的另一個基礎技術——特性。
1、什麼是特性:就部落客的了解,特性就是在類的類名稱、屬性、方法等上面加一個标記,使這些類、屬性、方法等具有某些統一的特征,進而達到某些特殊的需要。比如:方法的異常捕捉,你是否還在某些可能出現異常的地方(例如資料庫的操作、檔案的操作等)經常使用try...catch。這個時候如果使用特性,就可以大大減少方法裡面的try...catch的使用。你隻需要定義一個專門捕捉異常的特性類ExceptionExAttribute,然後給這個特性類做些特殊處理,比如給它增加一個AOP攔截的功能(AOP攔截的方式很多,有興趣可以搜搜看,園子裡面很多類似的文章)。那麼在可能出現異常的方法名稱上面加上一個[ExceptionEx]特性标簽,這個方法就具有自動捕捉異常的能力。還是加上官方定義:
特性提供功能強大的方法,用以将中繼資料或聲明資訊與代碼(程式集、類型、方法、屬性等)相關聯。 特性與程式實體關聯後,即可在運作時使用名為“反射”的技術查詢特性。
特性具有以下屬性:
特性可向程式中添加中繼資料。 中繼資料是有關在程式中定義的類型的資訊。 所有的 .NET 程式集都包含指定的一組中繼資料,這些中繼資料描述在程式集中定義的類型和類型成員。 可以添加自定義特性,以指定所需的任何附加資訊。
可以将一個或多個特性應用到整個程式集、子產品或較小的程式元素(如類和屬性)。
特性可以與方法和屬性相同的方式接受參數。
程式可以使用反射檢查自己的中繼資料或其他程式内的中繼資料。
(以上來自MSDN)
2、為什麼需要特性:這個上面已經簡單介紹過,特性能大大減少統一需求的代碼量。其他不說,至少它能讓我們的代碼看上去更大氣點吧~~
3、特性的使用:部落客這次還是打算從三個友善分别介紹下特性的正常使用方法。當然這幾種方式都是部落客原來用過的,可能不是最好的舉例場景,但是也算比較典型的特性用法吧。
(1)類的屬性上面特性的用法:
之是以将這個放在最前面介紹是因為部落客最近做的一個BS項目正好用到,并且使用場景也比較典型。首先介紹下使用場景:最近項目有一個需求,BS界面需要一個拖拽的功能。如下圖

當将左邊的3個div拖到右邊來時,每個div都有自己的特有屬性,比如2部門拖過來時,要顯示如下屬性:
1和3部門拖過來時可能對應的屬性不同。
設計思路:每個div對應的Model,每個Model裡面有自己特有的屬性,然後屬性上面加上特性顯示屬性的名稱和預設值,以及界面應該呈現的html标簽。
實作代碼:
首先來看自定義的一個特性類:
對應的Model:
然後在界面的拖放事件結束時通過js發送ajax請求來得到界面要呈現的html:
對應的C#方法:
GetModelByType方法結果簡單構造下然後将屬性的鍵值對傳回給js方法,然後再由js追加到界面上面。這樣通過特性和反射的結合能很快完成這個小功能的設計。
(2)類的方法上面特性的用法:
這個用法.Net framework裡面就很多,如果MVC裡面Filter過濾器的用法:
View Code
在Controller裡面方法上面加上特性:
這個ActionFilterAttribute這個特性用法裡面就有異常的攔截機制,和前面說的自定義的異常攔截是相同的。
(3)類上面特性的用法:
類上面特性的用法其實.Net裡面也很多。比如為了避免new一個對象而使用的MEF就是一個很有說服力的例子:
在定義個類實作一個接口時:
定義接口沒有任何特殊:
然後在使用時隻需要加一個[Import]标簽,這個變量就會在編譯時自動new一個Impc_TB_Test變量:
在使用service變量時,就可以直接把它當做一個Impc_TB_Test對象來使用。是不是很友善。
這幾種常見用法都是部落客用過的覺得比較好的場景,當然特性的用法肯定遠不止如此,歡迎大俠們指正拍磚~~