網站首頁 編程語言 正文
在前面介紹的代碼中有使用特性,這些特性都是Microsoft定義好的,作為.NET Framework類庫的一部分,許多特性都得到了C#編譯器的支持。
.NET Frmework也允許定義自己的特性。自定義特性允許把自定義元數據與程序元素關聯起來。這些元數據是在編譯過程中創建的,并嵌入到程序集中。這些特性不會影響編譯過程,因為編譯器不能識別它們,但這些特性在應用于程序元素時,可以在編譯好的程序集中用作元數據。這些元數據在文檔說明中很有用。使自定義特性起很大作用的是反射(https://www.jb51.net/article/244259.htm)技術,代碼可以讀取這些元數據,使用它們在運行期間作決策。
編寫自定義特性
[FieldName("Social")]
public string SocialNumber
{
...
}
當C#編譯器發現SocialNumber屬性應用了一個FieldName特性時,首先會把字符串Attribute追加到FieldName這個名稱后面,形成一個組合名稱FieldNameAttribute,然后在其搜索路徑的所有名稱空間(即在using語句中提及的名稱空間)中搜索FieldNameAttribute類。但如果該特性的名稱以字符串Attribute結尾,編譯器就不會把這個字符串加到組合名稱中。
因此上面的代碼等價于:
[FieldNameAttribute("Social")]
public string SocialNumber
{
...
}
1.AttributeUsage特性
自定義的特性類需要直接或間接派生自System.Attribute。這個類還應包含控制用法的信息:
- *特性可以應用到哪些類型的程序元素上(類,結構,屬性和方法等)
- *特性是否可以多次應用到同一個程序元素上
- *特性在應用到類或接口上時,是否由派生類和接口繼承
- *這個特性有哪些必選和可選參數
如果編譯器找不到對應的特性類,或者找到一個這樣的特性類,但使用特性的方式與特性類中的信息不匹配,編譯器就會產生一個編譯錯誤。
定義FieldNameAttribute特性
[AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=false)]
public class FieldNameAttribute:Attribute
{
private string name;
public FieldNameAttribute(string name)
{
this.name = name;
}
}
特性類FieldNameAttribute本身用了一個特性System.AttributeUsage來標記。這是Microsoft定義的一個特性,C#編譯器為它提供了特殊的支持。AttributeUsage主要用于標識自定義特性可以應用到哪些類型的程序元素上。這些信息由它的第一個參數AttributeTargets給出,該參數是必選的,其類型是枚舉類型AttributeTargets。上面的例子,指定FieldNameAttribute特性只能應用到屬性上。
AttributeTargets枚舉的成員如下:
上面列出了可以應用該特性的所有程序元素。在把特性應用到程序元素上時,應把特性放在元素前面的方括號中:
[FieldName("Social")]
public string SocialNumber
{
...
}
但在應用到Assembly和Module時,特性可以應用到整個程序集或模塊中,而不是應用到代碼中的一個元素上,在這種情況下,這個特性可以放在源代碼的任何地方,但需要使用關鍵字Assembly和Module作為前綴:
[assembly:FieldName("Social")]
[module:FieldName("Social")]
在指定自定義特性的有效目標元素時,可以使用OR運算符(|)把這些值組合起來:
[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指定自定義特性可以應用到所有類型的程序元素上。
AttributeUsage特性還包含另外兩個參數:AllowMultiple和Inherited。它們用不同的語法來指定:參數名 = 參數值,而不是只給出這些參數的值。這些參數是可選的。
- AllowMultiple參數表示一個特性是否可以多次應用到同一項上。
- Inherited參數表示應用到類或接口上的特性是否自動應用到所以派生的類或接口上。如果特性應用到方法或屬性上,它就自動應用到它們的重寫版本上。
2.指定特性參數
[FieldName("Social")]
public string SocialNumber
{
...
}
編譯器會檢查傳遞給特性的參數(在本例中,是一個字符串),并產兆該特性類中帶這些參數的構造函數。如果找到匹配的構造函數,編譯器就會把指定的元數據傳遞給程序集。如果找不到,就會生成一個編譯錯誤。反射()會從程序集中讀取元數據,并實例化它們表示的特性類。因此,編譯器需要確保存在這樣的構造函數,才能在運行期間實例化指定的特性。
3.特性的可選參數
在AttributeUsage特性中,使用參數名 = 參數值語法把可選參數添加到特性中。這種語法指定可選參數的名稱和值,它通過特性類中的公共屬性或字段起作用:
[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="可選參數值")]
public string SocialNumber
{
...
}
原文鏈接:https://www.cnblogs.com/afei-24/p/6867935.html
相關推薦
- 2023-08-15 vite打包報錯 Rollup failed to resolve
- 2022-10-26 c語言數據結構之棧和隊列詳解(Stack&Queue)_C 語言
- 2023-07-06 css實現高亮模式和黑暗模式
- 2022-06-27 Python查找多個字典公共鍵key的方法_python
- 2022-06-20 golang常用加密解密算法總結(AES、DES、RSA、Sha1、MD5)_Golang
- 2022-10-18 pandas重復行刪除操作df.drop_duplicates和df.duplicated的區別_p
- 2022-07-01 ASP.NET中的Web控件介紹_基礎應用
- 2022-09-24 Go?iota關鍵字與枚舉類型實現原理_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支