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