C#中Attribute特性的用法
開(kāi)篇語(yǔ)
本文開(kāi)始之前,首先我想問(wèn)下大家對(duì)于屬性和特性知道多少?屬性和特性又有何區(qū)別?
對(duì)于該單詞,我更想把它稱(chēng)之為:特性。對(duì)于屬性和特性就是名稱(chēng)上有糾葛(不知道你們迷不迷,反正我寫(xiě)本文之前我是迷了),什么是屬性?屬性是面向?qū)ο缶幊痰幕靖拍睿峁┝藢?duì)私有字段的訪(fǎng)問(wèn)封裝,在C#中以get和set訪(fǎng)問(wèn)器方法實(shí)現(xiàn)對(duì)可讀可寫(xiě)屬性的操作,提供了安全和靈活的數(shù)據(jù)訪(fǎng)問(wèn)封裝。什么是特性?下面內(nèi)容就說(shuō)明下:
介紹
使用特性,可以有效地將元數(shù)據(jù)或聲明性信息與代碼(程序集、類(lèi)型、方法、屬性等)相關(guān)聯(lián)。將特性與程序?qū)嶓w相關(guān)聯(lián)后,可以在運(yùn)行時(shí)使用 反射 這項(xiàng)技術(shù)查詢(xún)特性。詳情 用于添加元數(shù)據(jù),如編譯器指令和注釋、描述、方法、類(lèi)等其他信息。.Net 框架提供了兩種類(lèi)型的特性:預(yù)定義特性和自定義特性。
簡(jiǎn)單總結(jié):定制特性attribute,本質(zhì)上是一個(gè)類(lèi),其為目標(biāo)元素提供關(guān)聯(lián)附加信息,并在運(yùn)行期以反射的方式來(lái)獲取附加信息。
常用特性
AttributeUsage
AttributeUsage特性用于控制如何應(yīng)用自定義特性到目標(biāo)元素,有三個(gè)數(shù)據(jù)屬性可用以修飾我們的自定義的屬性
ValidOn | 規(guī)定特性可被放置的語(yǔ)言元素。它是枚舉器 AttributeTargets 的值的組合。默認(rèn)值是 AttributeTargets.All。 |
---|---|
AllowMultiple | 定義了是否可在同一個(gè)程序?qū)嶓w上同時(shí)使用多個(gè)屬性進(jìn)行修飾 |
Inherited | 定義了自定義屬性的修飾是否可由被修飾類(lèi)的派生類(lèi)繼承 |
[AttributeUsage(validOn: AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public class HelpAttribute : Attribute { }
表示該特定只能標(biāo)識(shí)在類(lèi)上,并且同一個(gè)類(lèi)上只能用一個(gè)屬性修飾,并且自定義屬性的修飾不能由修飾類(lèi)的派生類(lèi)繼承。
Flags
以Flags特性來(lái)將枚舉數(shù)值看作位標(biāo)記,而非單獨(dú)的數(shù)值,例如我有如下的一個(gè)需求,當(dāng)我想要取得用戶(hù)信息的時(shí)候,會(huì)先從本地緩存中查找,找不到然后從分布式緩存中查找,最后找不到再?gòu)臄?shù)據(jù)庫(kù)中查詢(xún)。但是有些場(chǎng)景我又不需要查詢(xún)數(shù)據(jù)庫(kù)。
所以會(huì)建立下面的這種模型
public UserEntity GetUserInfo(List<DataSource> dataSources) { var xxxx = new UserEntity(); if(dataSources.Any(DataSource.Local) { //從本地緩存中獲取 return xxxx; } if(dataSources.Any(DataSource.Distribution) { //從分布式緩存中獲取 //更新本地緩存 return xxxx; } if(dataSources.Any(DataSource.DB) { //從DB中獲取 //更新分布式緩存 //更新本地緩存 } return xxxx; }
但是每次調(diào)用者都去構(gòu)建一個(gè)List,比較麻煩,此時(shí)我們可以使用枚舉中的Flags特性,修改程序如下:
首先是枚舉的定義上,要加上 [Flags] 特性標(biāo)簽,并且定義 一般都是 2的n次方,主要是便于位移運(yùn)算
/// <summary> ///數(shù)據(jù)取得地方 /// </summary> [Flags] public enum DataSource { /// <summary> ///本地緩存 /// </summary> [Description("本地緩存")] LocalCache = 1, /// <summary> ///分布式緩存 /// </summary> [Description("分布式緩存")] DistributeCache = 2, /// <summary> ///數(shù)據(jù)庫(kù) /// </summary> [Description("數(shù)據(jù)庫(kù)")] DB = 4, }
修改代碼
public UserEntity GetUserInfo(DataSource dataSources) { var xxxx = new UserEntity(); if(dataSources.HasFlags(DataSource.Local) { //從本地緩存中獲取 return xxxx; } if(dataSources.HasFlags(DataSource.Distribution) { //從分布式緩存中獲取 //更新本地緩存 return xxxx; } if(dataSources.HasFlags(DataSource.DB) { //從DB中獲取 //更新分布式緩存 //更新本地緩存 } return xxxx; }
調(diào)用的地方,可以用過(guò)“|”來(lái)指定,例如我只想用分布式緩存和數(shù)據(jù)庫(kù),那么:
var userInfo = GetUserInfo(DataSource.Distribution | DataSource.DB);
該例子摘抄自:http://www.dbjr.com.cn/article/254408.htm
DllImport
DllImport特性,可以讓我們調(diào)用非托管代碼,所以我們可以使用DllImport特性引入對(duì)Win32 API函數(shù)的調(diào)用
[System.Runtime.InteropServices.DllImport("user32.dll")] extern static void SampleMethod();
Serializable
Serializable特性表明了應(yīng)用的元素可以被序列化(serializated)
[Serializable] public class SampleClass { // Objects of this type can be serialized. }
Conditional
Conditional特性,用于條件編譯,在調(diào)試時(shí)使用。注意:Conditional不可應(yīng)用于數(shù)據(jù)成員和屬性。
自定義特性
可通過(guò)定義特性類(lèi)創(chuàng)建自己的自定義特性,特性類(lèi)是直接或間接派生自 Attribute 的類(lèi),可快速輕松地識(shí)別元數(shù)據(jù)中的特性定義。假設(shè)我們希望使用編寫(xiě)類(lèi)的程序員名字來(lái)標(biāo)記該類(lèi),那么我們就需要自定義一個(gè)Author特性類(lèi)
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)] public class AuthorAttribute : Attribute { public string AuthorName; public double version; public AuthorAttribute(string authorName) { this.AuthorName = authorName; version = 1.0; } }
類(lèi)名 AuthorAttribute
是該特性的名稱(chēng),即 Author
加上 Attribute
后綴。由于該類(lèi)繼承自 System.Attribute
,因此它是一個(gè)自定義特性類(lèi)。構(gòu)造函數(shù)的參數(shù)是自定義特性的位置參數(shù)。在此示例中,name
是位置參數(shù)。所有公共讀寫(xiě)字段或?qū)傩远际敲麉?shù)。在本例中,version
是唯一的命名參數(shù)。
請(qǐng)注意,使用
AttributeUsage
特性可使Author
特性?xún)H對(duì)類(lèi)和struct
聲明有效。
可按照下面的方式使用特性
[Author("張三", version = 1.1)] [Author("李四", version = 1.2)] public class SampleClass { // 業(yè)務(wù)邏輯代碼 }
獲取自定義參數(shù)
var attr = typeof(SampleClass).GetCustomAttributes(typeof(AuthorAttribute), true);
GetCustomAttributes 會(huì)以數(shù)組形式返回 Author 對(duì)象和任何其他特性對(duì)象
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于C#轉(zhuǎn)換二進(jìn)制所引起的一些思考
這篇文章主要給大家介紹了關(guān)于C#轉(zhuǎn)換二進(jìn)制所引起的一些思考,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07C#實(shí)現(xiàn)簡(jiǎn)單過(guò)濾非法字符實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)簡(jiǎn)單過(guò)濾非法字符的方法,涉及C#針對(duì)字符串遍歷與判斷的相關(guān)技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-11-11c#項(xiàng)目實(shí)現(xiàn)發(fā)布到服務(wù)器全過(guò)程
這篇文章主要介紹了c#項(xiàng)目實(shí)現(xiàn)發(fā)布到服務(wù)器全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04C#實(shí)現(xiàn)生成mac地址與IP地址注冊(cè)碼的兩種方法
這篇文章主要介紹了C#實(shí)現(xiàn)生成mac地址與IP地址注冊(cè)碼的兩種方法,非常實(shí)用的技巧,需要的朋友可以參考下2014-09-09C#實(shí)現(xiàn)ProperTyGrid自定義屬性的方法
這篇文章主要介紹了C#實(shí)現(xiàn)ProperTyGrid自定義屬性的方法,主要通過(guò)接口ICustomTypeDescriptor實(shí)現(xiàn),需要的朋友可以參考下2014-09-09C#實(shí)現(xiàn)學(xué)員信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)學(xué)員信息管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06