網(wǎng)站首頁 編程語言 正文
在前面介紹的代碼中有使用特性,這些特性都是Microsoft定義好的,作為.NET Framework類庫的一部分,許多特性都得到了C#編譯器的支持。
.NET Frmework也允許定義自己的特性。自定義特性允許把自定義元數(shù)據(jù)與程序元素關(guān)聯(lián)起來。這些元數(shù)據(jù)是在編譯過程中創(chuàng)建的,并嵌入到程序集中。這些特性不會影響編譯過程,因?yàn)榫幾g器不能識別它們,但這些特性在應(yīng)用于程序元素時(shí),可以在編譯好的程序集中用作元數(shù)據(jù)。這些元數(shù)據(jù)在文檔說明中很有用。使自定義特性起很大作用的是反射(https://www.jb51.net/article/244259.htm)技術(shù),代碼可以讀取這些元數(shù)據(jù),使用它們在運(yùn)行期間作決策。
編寫自定義特性
[FieldName("Social")]
public string SocialNumber
{
...
}
當(dāng)C#編譯器發(fā)現(xiàn)SocialNumber屬性應(yīng)用了一個(gè)FieldName特性時(shí),首先會把字符串Attribute追加到FieldName這個(gè)名稱后面,形成一個(gè)組合名稱FieldNameAttribute,然后在其搜索路徑的所有名稱空間(即在using語句中提及的名稱空間)中搜索FieldNameAttribute類。但如果該特性的名稱以字符串Attribute結(jié)尾,編譯器就不會把這個(gè)字符串加到組合名稱中。
因此上面的代碼等價(jià)于:
[FieldNameAttribute("Social")]
public string SocialNumber
{
...
}
1.AttributeUsage特性
自定義的特性類需要直接或間接派生自System.Attribute。這個(gè)類還應(yīng)包含控制用法的信息:
- *特性可以應(yīng)用到哪些類型的程序元素上(類,結(jié)構(gòu),屬性和方法等)
- *特性是否可以多次應(yīng)用到同一個(gè)程序元素上
- *特性在應(yīng)用到類或接口上時(shí),是否由派生類和接口繼承
- *這個(gè)特性有哪些必選和可選參數(shù)
如果編譯器找不到對應(yīng)的特性類,或者找到一個(gè)這樣的特性類,但使用特性的方式與特性類中的信息不匹配,編譯器就會產(chǎn)生一個(gè)編譯錯(cuò)誤。
定義FieldNameAttribute特性
[AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=false)]
public class FieldNameAttribute:Attribute
{
private string name;
public FieldNameAttribute(string name)
{
this.name = name;
}
}
特性類FieldNameAttribute本身用了一個(gè)特性System.AttributeUsage來標(biāo)記。這是Microsoft定義的一個(gè)特性,C#編譯器為它提供了特殊的支持。AttributeUsage主要用于標(biāo)識自定義特性可以應(yīng)用到哪些類型的程序元素上。這些信息由它的第一個(gè)參數(shù)AttributeTargets給出,該參數(shù)是必選的,其類型是枚舉類型AttributeTargets。上面的例子,指定FieldNameAttribute特性只能應(yīng)用到屬性上。
AttributeTargets枚舉的成員如下:
上面列出了可以應(yīng)用該特性的所有程序元素。在把特性應(yīng)用到程序元素上時(shí),應(yīng)把特性放在元素前面的方括號中:
[FieldName("Social")]
public string SocialNumber
{
...
}
但在應(yīng)用到Assembly和Module時(shí),特性可以應(yīng)用到整個(gè)程序集或模塊中,而不是應(yīng)用到代碼中的一個(gè)元素上,在這種情況下,這個(gè)特性可以放在源代碼的任何地方,但需要使用關(guān)鍵字Assembly和Module作為前綴:
[assembly:FieldName("Social")]
[module:FieldName("Social")]
在指定自定義特性的有效目標(biāo)元素時(shí),可以使用OR運(yùn)算符(|)把這些值組合起來:
[AttributeUsage(AttributeTargets.Property |AttributeTargets.Field,
AllowMultiple=false, Inherited=false)]
public class FieldNameAttribute:Attribute
{
private string name;
public FieldNameAttribute(string name)
{
this.name = name;
}
}
也可以使用AttributeTargets.All指定自定義特性可以應(yīng)用到所有類型的程序元素上。
AttributeUsage特性還包含另外兩個(gè)參數(shù):AllowMultiple和Inherited。它們用不同的語法來指定:參數(shù)名 = 參數(shù)值,而不是只給出這些參數(shù)的值。這些參數(shù)是可選的。
- AllowMultiple參數(shù)表示一個(gè)特性是否可以多次應(yīng)用到同一項(xiàng)上。
- Inherited參數(shù)表示應(yīng)用到類或接口上的特性是否自動應(yīng)用到所以派生的類或接口上。如果特性應(yīng)用到方法或?qū)傩陨?,它就自動?yīng)用到它們的重寫版本上。
2.指定特性參數(shù)
[FieldName("Social")]
public string SocialNumber
{
...
}
編譯器會檢查傳遞給特性的參數(shù)(在本例中,是一個(gè)字符串),并產(chǎn)兆該特性類中帶這些參數(shù)的構(gòu)造函數(shù)。如果找到匹配的構(gòu)造函數(shù),編譯器就會把指定的元數(shù)據(jù)傳遞給程序集。如果找不到,就會生成一個(gè)編譯錯(cuò)誤。反射()會從程序集中讀取元數(shù)據(jù),并實(shí)例化它們表示的特性類。因此,編譯器需要確保存在這樣的構(gòu)造函數(shù),才能在運(yùn)行期間實(shí)例化指定的特性。
3.特性的可選參數(shù)
在AttributeUsage特性中,使用參數(shù)名 = 參數(shù)值語法把可選參數(shù)添加到特性中。這種語法指定可選參數(shù)的名稱和值,它通過特性類中的公共屬性或字段起作用:
[AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=false)]
public class FieldNameAttribute:Attribute
{
private string name;
public FieldNameAttribute(string name)
{
this.name = name;
}
public string Comment
{
get;set;
}
}
[FieldName("Social",Comment="可選參數(shù)值")]
public string SocialNumber
{
...
}
原文鏈接:https://www.cnblogs.com/afei-24/p/6867935.html
相關(guān)推薦
- 2022-05-26 Python借助with語句實(shí)現(xiàn)代碼段只執(zhí)行有限次_python
- 2023-11-15 Latex解決表格過寬問題,自適應(yīng)調(diào)整寬度;自動調(diào)整適合的表格大小
- 2022-01-29 fastadmin自定義按鈕url,去掉默認(rèn)的ids參數(shù)
- 2022-09-19 Tomcat10配置端口號為443(使用https訪問)_Tomcat
- 2022-07-09 android開機(jī)自動啟動app的解決方法_Android
- 2023-03-01 shell?wait等待命令的具體使用_linux shell
- 2022-12-12 Android?DataBinding布局的加載深入探究_Android
- 2022-11-30 Android?Binder?通信原理圖文詳解_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支