日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

C# 特性(attribute)

發(fā)布時(shí)間:2025/5/22 C# 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# 特性(attribute) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、什么是特性

  特性是一種允許我們向程序的程序集添加元數(shù)據(jù)的語(yǔ)言結(jié)構(gòu),它是用于保存程序結(jié)構(gòu)信息的某種特殊類型的類。

  MSDN中對(duì)它的解釋是:特性提供功能強(qiáng)大的方法以將聲明信息與 C# 代碼(類型、方法、屬性等)相關(guān)聯(lián)。特性與程序?qū)嶓w關(guān)聯(lián)后,即可在運(yùn)行時(shí)使用名為“反射”的技術(shù)查詢屬性。

  (有關(guān)元數(shù)據(jù)和反射的知識(shí),點(diǎn)擊查看 C# 反射)

?

二、使用特性

  特性的目的是告訴編譯器把程序結(jié)構(gòu)的某組元數(shù)據(jù)嵌入程序集,它可以放置在幾乎所有的聲明中(但特定的屬性可能限制在其上有效的聲明類型)。其語(yǔ)法為:

  ● 在結(jié)構(gòu)前放置特性片段來(lái)運(yùn)用特性

  ● 特性片段被方括號(hào)包圍,其中是特性名和特性的參數(shù)列表

  例:

  [Serializable] //不含參數(shù)的特性public class MyClass{...}[MyAttribute("firt","second","finally")] //帶有參數(shù)的特性   public class MyClass {...}

  注: 大多數(shù)特性只針對(duì)直接跟隨在一個(gè)或多個(gè)特性片段后的結(jié)構(gòu)

?

  單個(gè)結(jié)構(gòu)可以運(yùn)用多個(gè)特性,使用時(shí)可以把獨(dú)立的特性片段互相疊在一起或使用分成單個(gè)特性片段,特性之間用逗號(hào)分隔

[Serializable] [MyAttribute("firt","second","finally")] //獨(dú)立的特性片段 ...

[MyAttribute("firt","second","finally"), Serializable] //逗號(hào)分隔
...

?

  某些屬性對(duì)于給定實(shí)體可以指定多次。例如,Conditional?就是一個(gè)可多次使用的屬性:

[Conditional("DEBUG"), Conditional("TEST1")] void TraceMethod() {// ... }

?

  ?特性的目標(biāo)是應(yīng)用該特性的實(shí)體。例如,特性可以應(yīng)用于類、特定方法或整個(gè)程序集。默認(rèn)情況下,特性應(yīng)用于它后面的元素。但是,您也可以顯式標(biāo)識(shí)要將特性應(yīng)用于方法還是它的參數(shù)或返回值。

C#中標(biāo)準(zhǔn)特性目標(biāo)名稱適用對(duì)象
assembly整個(gè)程序集
module當(dāng)前程序集模塊(不同于Visual Basic 模塊)
field在類或結(jié)構(gòu)中的字段
eventEvent
method方法或get和set屬性訪問(wèn)器
param方法參數(shù)或set屬性訪問(wèn)器的參數(shù)
propertyProperty
return方法、屬性索引器或get屬性訪問(wèn)器的返回值
type結(jié)構(gòu)、類、接口、枚舉或委托
typevar指定使用泛型結(jié)構(gòu)的類型參數(shù)

?

三、自定義特性

  特性的用法雖然很特殊,但它只是某個(gè)特殊類型的類。

?

  3.1 聲明自定義的特性

    總體上聲明特性和聲明其他類是一樣的,只是所有的特性都派生自System.Attribute。根據(jù)慣例,特性名使用Pascal命名法并且以Attribute后綴結(jié)尾,當(dāng)為目標(biāo)應(yīng)用特性時(shí),我們可以不使用后綴。如:對(duì)于SerializableAttribute

和MyAttributeAttribute這兩個(gè)特性,我們?cè)诎阉鼞?yīng)用到結(jié)構(gòu)的時(shí)候可以使用[Serializable和MyAttribute短名

public class MyAttributeAttribute : System.Attribute {...}

    當(dāng)然它也有構(gòu)造函數(shù)。和其他類一樣,每個(gè)特性至少有一個(gè)公共構(gòu)造函數(shù),如果你不聲明構(gòu)造函數(shù),編譯器會(huì)產(chǎn)生一個(gè)隱式、公共且無(wú)參的構(gòu)造函數(shù)。

public class MyAttributeAttribute : System.Attribute{public string Description;public string ver;public string Reviwer;public MyAttributeAttribute(string desc,string ver,string Rev) //構(gòu)造函數(shù) {Description = desc;this.ver = ver;Reviwer = Rev;}}

?

  3.2? 限制特性的使用

  前面我們已經(jīng)知道,可以在類上面運(yùn)用特性,而特性本身就是類,有一個(gè)很重要的預(yù)定義特性AttributeUsage可以運(yùn)用到自定義特性上,我們可以用它來(lái)限制特性使用在某個(gè)目標(biāo)類型上

  下面的例子使自定義的特性只能應(yīng)用到方法和類上

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]public class MyAttributeAttribute : System.Attribute{...}

  簡(jiǎn)單解讀一下AttributeUsage特性,它有三個(gè)重要的公共屬性,如下表

名字意義默認(rèn)值
ValidOn指定特性允許的目標(biāo)類型。構(gòu)造函數(shù)的第一個(gè)參數(shù)必須是AttributeTarget類型的枚舉值?
Inherited布爾值,指示特性能否被派生類和重寫成員繼承?true
AllowMultiple布爾值,指示特性能否被重復(fù)放置在同一個(gè)程序?qū)嶓w前多次?false

  在vs中按f12查閱定義我們可以看到,AttributeTarget枚舉的成員有

  看一個(gè)小例子

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, //必須的,指示MyAttribute只能應(yīng)用到類和方法上Inherited = false, //可選,表明不能被派生類繼承AllowMultiple = false)] //可選,表明不能有MyAttribute的多個(gè)實(shí)例應(yīng)用到同一個(gè)目標(biāo)上public class MyAttributeAttribute : System.Attribute{...}

?

  3.3訪問(wèn)特性

  定義好特性了,怎么進(jìn)行訪問(wèn)呢?對(duì)于自定義的特性,我們可以用Type中的IsDefined和GetCustomAttributes方法來(lái)獲取

?

  3.3.1 使用IsDefined方法

  public abstract bool IsDefined(Type attributeType, bool inherit),它是用來(lái)檢測(cè)某個(gè)特性是否應(yīng)用到了某個(gè)類上

  參數(shù)說(shuō)明:? ? attributeType :?要搜索的自定義特性的類型。 搜索范圍包括派生的類型。

        inherit:true 搜索此成員繼承鏈,以查找這些屬性;否則為 false。 屬性和事件,則忽略此參數(shù)

        返回結(jié)果:?true 如果一個(gè)或多個(gè)實(shí)例 attributeType 或其派生任何的類型為應(yīng)用于此成員; 否則為 false。

?  下面代碼片段是用來(lái)檢查MyAttribute特性是否被運(yùn)用到MyClass類

MyClass mc = new MyClass(); Type t = mc.GetType(); bool def = t.IsDefined(typeof(MyAttributeAttribute),false); if (def)Console.WriteLine("MyAttribute is defined!");

?

?  3.3.2 使用GetCustomAttributes方法

?  public abstract object[] GetCustomAttributes(bool inherit),調(diào)用它后,會(huì)創(chuàng)建每一個(gè)與目標(biāo)相關(guān)聯(lián)的特性的實(shí)例

  參數(shù)說(shuō)明: inherit:?true 搜索此成員繼承鏈,以查找這些屬性;否則為 false

        返回結(jié)果:返回所有應(yīng)用于此成員的自定義特性的數(shù)組,因此我們必須將它強(qiáng)制轉(zhuǎn)換為相應(yīng)的特性類型

?

//自定義特性 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class MyAttributeAttribute : System.Attribute{public string Description;public string ver;public string Reviwer;public MyAttributeAttribute(string desc,string ver,string Rev){Description = desc;this.ver = ver;Reviwer = Rev;}}//定義類 [MyAttribute("firt","second","finally")]class MyClass{}static void Main(string[] args){MyClass mc = new MyClass();Type t = mc.GetType();Object[] obj = t.GetCustomAttributes(false);foreach(Attribute a in obj){MyAttributeAttribute attr = a as MyAttributeAttribute;if(attr != null){Console.WriteLine("Description : {0}", attr.Description);Console.WriteLine("ver : {0}", attr.ver);Console.WriteLine("review: {0}", attr.Reviwer);}}}

結(jié)果:

?

四、預(yù)定義的特性

  4.1 Obsolete特性

  Obsolete特性將public ObsoleteAttribute()程序結(jié)構(gòu)標(biāo)注為過(guò)期的,并且在代碼編譯時(shí)顯式有用的警告信息,它有三種重載

  public ObsoleteAttribute()

  public ObsoleteAttribute(string message)  參數(shù)說(shuō)明: message:描述了可選的變通方法文本字符串。

  public ObsoleteAttribute(string message, bool error)  參數(shù)說(shuō)明:message:描述了可選的變通方法文本字符串。  error:true 如果使用過(guò)時(shí)的元素將生成編譯器錯(cuò)誤; false 如果使用它將生成編譯器警告。

  舉個(gè)例子:

using System; using System.Runtime.CompilerServices;namespace 特性 {class Program{[Obsolete("Use method SuperPrintOut")]static void Print(string str,[CallerFilePath] string filePath = ""){Console.WriteLine(str);Console.WriteLine("filePath {0}", filePath);}static void Main(string[] args){string path = "no path";Print("nothing",path);Console.ReadKey();}} }

運(yùn)行沒(méi)有問(wèn)題,不過(guò)出現(xiàn)了警告:

如果將?[Obsolete("Use method SuperPrintOut")]? 改成[Obsolete("Use method SuperPrintOut",true)] 的話,編譯則會(huì)出現(xiàn)錯(cuò)誤信息

?

?

?  4.2 Conditional 特性

  public ConditionalAttribute(string conditionString),指示編譯器,如果定義了conditionString編譯符號(hào),就和普通方法沒(méi)有區(qū)別,否則忽略代碼中方法這個(gè)方法的所有調(diào)用

#define fun //定義編譯符號(hào) using System; using System.Runtime.CompilerServices;namespace 特性 {class Program{[Conditional("fun")]static void Fun(string str){Console.WriteLine(str);}static void Main(string[] args){Fun("hello");Console.ReadKey();}}}

  由于定義了fun,所以Fun函數(shù)會(huì)被調(diào)用,如果沒(méi)有定義,這忽略Fun函數(shù)的調(diào)用

?

  4.3 調(diào)用者信息特性

  調(diào)用者信息特性可以訪問(wèn)文件路徑、代碼行數(shù)、調(diào)用成員的名稱等源代碼信息,這三個(gè)特性的名稱分別為CallerFilePath、CallerLineNumber和CallerMemberName,這些方法只能用于方法中的可選參數(shù)

using System; using System.Runtime.CompilerServices;namespace 特性 {class Program{static void Print(string str,[CallerFilePath] string filePath = "",[CallerLineNumber] int num = 0,[CallerMemberName] string name = ""){Console.WriteLine(str);Console.WriteLine("filePath {0}", filePath);Console.WriteLine("Line {0}", num);Console.WriteLine("Call from {0}", name);}static void Main(string[] args){Print("nothing");Console.ReadKey();}} }

?

?  

?

轉(zhuǎn)載于:https://www.cnblogs.com/forever-Ys/p/10428568.html

總結(jié)

以上是生活随笔為你收集整理的C# 特性(attribute)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。