C# 特性[Attribute]
開篇語
本文開始之前,首先我想問下大家對於屬性和特性知道多少?屬性和特性又有何區別?
對於該單詞,我更想把它稱之為:特性。對於屬性和特性就是名稱上有糾葛(不知道你們迷不迷,反正我寫本文之前我是迷了),什麼是屬性?屬性是物件導向程式設計的基本概念,提供了對私有欄位的訪問封裝,在C#中以get和set訪問器方法實現對可讀可寫屬性的操作,提供了安全和靈活的資料訪問封裝。什麼是特性?下面內容就說明下:
介紹
使用特性,可以有效地將後設資料或宣告性資訊與程式碼(程式集、型別、方法、屬性等)相關聯。將特性與程式實體相關聯後,可以在執行時使用 反射 這項技術查詢特性。詳情 用於新增後設資料,如編譯器指令和註釋、描述、方法、類等其他資訊。.Net 框架提供了兩種型別的特性:預定義特性和自定義特性。
簡單總結:定製特性attribute,本質上是一個類,其為目標元素提供關聯附加資訊,並在執行期以反射的方式來獲取附加資訊。
常用特性
AttributeUsage
AttributeUsage特性用於控制如何應用自定義特性到目標元素,有三個資料屬性可用以修飾我們的自定義的屬性
[AttributeUsage(validOn: AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class HelpAttribute : Attribute
{
}
表示該特定只能標識在類上,並且同一個類上只能用一個屬性修飾,並且自定義屬性的修飾不能由修飾類的派生類繼承。
Flags
以Flags特性來將列舉數值看作位標記,而非單獨的數值,例如我有如下的一個需求,當我想要取得使用者資訊的時候,會先從本地快取中查詢,找不到然後從分散式快取中查詢,最後找不到再從資料庫中查詢。但是有些場景我又不需要查詢資料庫。
所以會建立下面的這種模型
public UserEntity GetUserInfo(List 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;
}
但是每次呼叫者都去構建一個List,比較麻煩,此時我們可以使用列舉中的Flags特性,修改程式如下:
首先是列舉的定義上,要加上 [Flags] 特性標籤,並且定義 一般都是 2的n次方,主要是便於位移運算
///
///資料取得地方
///
[Flags]
public enum DataSource
{
///
///本地快取
///
[Description("本地快取")]
LocalCache = 1,
///
///分散式快取
///
[Description("分散式快取")]
DistributeCache = 2,
///
///資料庫
///
[Description("資料庫")]
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;
}
呼叫的地方,可以用過“|”來指定,例如我只想用分散式快取和資料庫,那麼:
var userInfo = GetUserInfo(DataSource.Distribution | DataSource.DB);
DllImport
DllImport特性,可以讓我們呼叫非託管程式碼,所以我們可以使用DllImport特性引入對Win32 API函式的呼叫
[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();
Serializable
Serializable特性表明了應用的元素可以被序列化(serializated)
[Serializable]
public class SampleClass
{
// Objects of this type can be serialized.
}
Conditional
Conditional特性,用於條件編譯,在除錯時使用。注意:Conditional不可應用於資料成員和屬性。
自定義特性
可透過定義特性類建立自己的自定義特性,特性類是直接或間接派生自 Attribute 的類,可快速輕鬆地識別後設資料中的特性定義。假設我們希望使用編寫類的程式設計師名字來標記該類,那麼我們就需要自定義一個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
,因此它是一個自定義特性類。建構函式的引數是自定義特性的位置引數。在此示例中,name
是位置引數。所有公共讀寫欄位或屬性都是命名引數。在本例中,version
是唯一的命名引數。
請注意,使用
AttributeUsage
特性可使Author
特性僅對類和struct
宣告有效。
可按照下面的方式使用特性
[Author("張三", version = 1.1)]
[Author("李四", version = 1.2)]
public class SampleClass
{
// 業務邏輯程式碼
}
獲取自定義引數
var attr = typeof(SampleClass).GetCustomAttributes(typeof(AuthorAttribute), true);
GetCustomAttributes 會以陣列形式返回 Author 物件和任何其他特性物件
參考文件
作者: AZRNG
出處:https://www.cnblogs.com/azrng/p/14735996.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1868/viewspace-2797595/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C# 中的特性 AttributeC#
- C#-特性(Attribute)C#
- [20181026]12c Attribute Clustering特性.txt
- C#特性C#
- 第32篇 .Net特性Attribute的高階使用
- .NET進階篇03-Reflection反射、Attribute特性反射
- [20181026]12c Attribute Clustering特性2.txt
- C#–特性詳解C#
- C# 9.0新特性C#
- C# 8新提案讓泛型Attribute成為現實C#泛型
- 13 個 C# 10 特性C#
- C# 10的新特性C#
- C# 11 都有哪些新特性?C#
- C#特性學習筆記C#筆記
- C#中Attribute的魅力:從基礎到高階AOP實戰C#
- Attribute Checks
- __attribute__
- clang attribute
- C# 9 新特性——init only setterC#
- 詳解C#特性和反射(四)C#反射
- 詳解C#特性和反射(三)C#反射
- 詳解C#特性和反射(二)C#反射
- 詳解C#特性和反射(一)C#反射
- C# 語言歷史版本特性(C# 1.0到C# 8.0彙總)C#
- C#語言歷史版本特性(C# 1.0到C# 8.0彙總)C#
- 【譯】C# 11 特性的早期預覽C#
- C# 9 新特性 —— 增強的 foreachC#
- According to TLD or attribute directive in tag file, attribute value does not accept any expressionExpress
- C# 使用特性的方式封裝報文C#封裝
- C# 9.0 新特性之模式匹配簡化C#模式
- C# 9 新特性 —— 增強的模式匹配C#模式
- C#物件導向三大特性總結C#物件
- selenium get_attribute
- C#中的 Attribute 與 Python/TypeScript 中的裝飾器是同個東西嗎C#PythonTypeScript
- C# 反射與特性(十):EMIT 構建程式碼C#反射MIT
- C# 9.0 新特性之 Lambda 棄元引數C#
- 你所不知道的 C# 10新特性C#
- 值得推薦的C#不同版本語言特性C#