特性真的好常見,用到地方也挺多的。程序員
在我平時工做中,看得比較多的特性有Web端:權限控制Authorize,過濾器,序列化,WCF,Webservice裏面也有不少,WebMethod,DataContract,還有作桌面端的用得最多的DllImport(能夠直接和Win32程序進行通訊),還有咱們經常使用到ORM,特性真的是無所不能,好像高逼格的地方,特性老是要來搞事。下面讓咱們一塊兒來看看特性到底是怎麼樣進行工做的。編程
特性:給類,方法等提供附加的功能,加強了軟件系統的靈活性,促進了功能的鬆散耦合。緩存
用特性呢,能夠避免多個相似的代碼段,建立更爲可讀和清晰的代碼。若是咱們能夠用.Net自帶的特性,咱們應該積極的用。函數
若是不能的話呢,咱們就能夠本身定義一個特性類。特性屬於聲明式編程的一種。性能
特性的好處:在不破壞類型封裝的前提下,增長一點額外的信息和功能。更加靈活了。就是能夠把業務和非業務邏輯區分得更開。spa
特性的壞處:定義。應用和反射特性能帶來許多便利。因此不少開發人員都喜歡用這些技術。而特性是存在元數據裏面的,可能會對性能有一些影響。由於要用反射的話,內部都必須掃描託管模塊的元數據,執行字符串比較來定位到指定的特性類。這樣操做是會耗費必定時間的。設計
假如對性能要求比較高的話,能夠緩存這些結果。code
一、業務場景blog
咱們平時不少公共邏輯,好比須要登陸才能夠進行受權。定義枚舉的時候,要帶上描述信息。ORM裏面的表名,列名映射關係。等等,還有不少地方,歡迎你們補充。繼承
4/1 特性的基本組成
從上圖能夠知道,特性是屬於元數據裏面的內容的,咱們也能夠經過反編譯來看看一下就能夠明白了。
一、以下例子:
class Program { [Text()] static void Main(string[] args) { Console.WriteLine("test"); } } public class TextAttribute : Attribute { }
咱們直接來看反編譯這段程序以後的IL;
從上面能夠看出,特性就是存在咱們元數據中的,並且還會去調用這個特性類的構造函數。
4/2 特性的基礎知識點
一、特性類,都必需要繼承自Attribute。這是由於面向CLR的全部編譯器都必須識別Attribute,而且最終能在元數據中生成特性信息。
編譯器有點傻的就是無論這個特性有沒有用,都會生成對應的元數據。
二、特性能夠應用於程序集,模塊,類型,字段,返回值,方法,參數,屬性,事件。
三、接下來咱們思考一個問題,咱們是否是定義一個特性,而後就能夠隨便用呢,用在屬性,方法,程序集,等等這些屬性上。假如咱們不指定特性的使用範圍呢,那咱們反射的時候,是否是要從方法,屬性,類上面都檢測一下是否含有這個特性呢,想一想這樣會給咱們性能帶來多大的影響呢。因此C#的設計者給咱們提供了一個 [AttributeUsage(AttributeTargets.All,AllowMultiple =true,Inherited =true)] 這個東西。
(1)AttributeUsage是一個特性類,能夠經過reflector看看它裏面就明白了
咱們直接須要傳三個參數的構造函數。 [AttributeUsage(AttributeTargets.All,AllowMultiple =true)]
AttributeTargets 這是一個枚舉。這個主要是用來指定特性的做用範圍。做爲一個程序員,咱們應該要根據須要來合理指定。
Inherited: 這個是說這個特性是否要進行繼承,若是要設置爲true的話呢,咱們反射去檢查它的派生類是否應用了這個特性。
通常狀況下,咱們不會把這個值設置爲true,這樣除了會額外的檢查,可能還會帶來混淆。因此通常建議定義特性類的時候,把它
設定爲sealed,減小混淆,避免此次檢查。
AllowMultiple:通常來講,太多特性屢次應用於同一個目標是沒有意義的。沒有什麼特別必要把這個值設置爲true。
4/3 特性的三部曲。
一、定義一個類,繼承自Attribute類,而且類名是以Attribute結尾的。
二、給指定的方法,屬性,類等等,給須要用特性的地方,加上特性打上標記。
三、經過反射來調用,使得特性生效。
不少人的錯覺,就是覺得寫上特性就能夠生效。全部讓特性生效的地方必定是主動應用了這個特性。
定製特性能有效,徹底是由於元數據和反射這個東東。
以前咱們沒用特性的時候,咱們普通的作法就是,假設如今是作Webservice開發,定義一個父類(Base),裏面寫一些通用的方法,而後全部的asmx都繼承這個父類,以後在每一個須要用的地方調用一下。
估計還有其餘作法,我以後再慢慢分享,今天實在是太累了...歡迎你們留言討論,祝你們中秋快樂。