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

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

生活随笔

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

C#

android 集成同一interface不同泛型_C# 基础知识系列- 10 反射和泛型(二)

發(fā)布時(shí)間:2025/3/15 C# 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 集成同一interface不同泛型_C# 基础知识系列- 10 反射和泛型(二) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

0. 前言

這篇文章延續(xù)《C# 基礎(chǔ)知識(shí)系列- 5 反射和泛型》,繼續(xù)介紹C#在反射所開(kāi)發(fā)的功能和做的努力。上一篇文章大概介紹了一下泛型和反射的一些基本內(nèi)容,主要是通過(guò)獲取對(duì)象的類型,然后通過(guò)這個(gè)類型對(duì)象操作對(duì)象。這一篇介紹一個(gè)在反射中很重要的內(nèi)容:特性,以及上一篇未完成的內(nèi)容——泛型在反射中的引用。

1. 特性

特性是一種類增強(qiáng)技術(shù),配合解析對(duì)應(yīng)的解析方法可以完成很多類原本沒(méi)有的功能。特性本質(zhì)是一種標(biāo)簽,可以標(biāo)注在類、方法、屬性等。它是類本身的一種信息擴(kuò)展,就像生活中一個(gè)人只有一個(gè)身份證號(hào),但是可以有多個(gè)身份一樣,而這些多出來(lái)的身份對(duì)于類來(lái)說(shuō)就是特性。特性雖然是對(duì)類的增強(qiáng),但不局限于在類上做標(biāo)記,屬性、方法上都可以。

在C#中特性分為三種,位映射特性、自定義特性和偽自定義特性。

位映射特性,舉個(gè)例子,在C#中一個(gè)類會(huì)有public、private、abstract(抽象類)、saled(不能繼承)等修飾符,而這些修飾符在C#編譯的過(guò)程中會(huì)生成一串二進(jìn)制碼,里面存放就是 是否是public、是否是private 等。這些就是位映射特性的一部分,位映射特性對(duì)我們來(lái)說(shuō)是無(wú)法進(jìn)行擴(kuò)展和修改的,所以就不做更多的介紹。

我們通常說(shuō)的特性一般指的是自定義特性,這部分特性也是我們能夠擴(kuò)展的,也是我們實(shí)際開(kāi)發(fā)中用的特性。

1.1 定義一個(gè)特性

如何正確的定義一個(gè)特性呢?在C#中,特性也是類的一種。所以聲明一個(gè)特性,就如同聲明一個(gè)類一樣,不同的是,這個(gè)類指定一個(gè)根父類是System.Attribute。所有自定義特性都是這個(gè)類的子類或者后代類,無(wú)一例外。同時(shí),C#提倡在定義一個(gè)特性類的時(shí)候,類名應(yīng)當(dāng)以Attribute結(jié)尾,在使用的時(shí)候可以自動(dòng)忽略。

示例:

public class DemoAttribute : Attribute { }

以上實(shí)例就是定義了一個(gè)很普通的特性類,用了也沒(méi)有任何用的特性。因?yàn)樘匦灾皇且环N標(biāo)簽。這個(gè)特性類可以用在任何支持特性的地方,當(dāng)這個(gè)特性標(biāo)記一個(gè)類的時(shí)候,目標(biāo)類的子類也將自動(dòng)獲取這個(gè)特性。

以上是一個(gè)特性的默認(rèn)行為,如果我們想要對(duì)此做一定限制的話,那么就需要用到特性System.AttributeUsageAttribute。這個(gè)特性類用來(lái)控制特性的使用方式。

public bool Inherited { get; set; }// 該特性是否可以被子類繼承,默認(rèn)是 True public bool AllowMultiple { get; set; }// 一個(gè)類是否可以多次使用該特性做標(biāo)記,默認(rèn)是 False public AttributeTargets ValidOn { get; }//獲取一組值,這組值標(biāo)識(shí)指示的屬性可應(yīng)用到的程序元素,該參數(shù)使用構(gòu)造方法賦值

我們?cè)賮?lái)看看AttributeTargets里有些什么吧。

[System.Flags] public enum AttributeTargets {Assembly = 1,// 表示特性是用在 Assembly上的,不常用Module = 2, //特性是用在 Module上的,不常用Class = 4, // 表示特性是用來(lái)類上的Struct = 8, //表示用在結(jié)構(gòu)體上Enum = 16, // 0x00000010 表示用在枚舉上Constructor = 32, // 0x00000020 構(gòu)造方法Method = 64, // 0x00000040 普通方法Property = 128, // 0x00000080 屬性Field = 256, // 0x00000100 字段Event = 512, // 0x00000200 事件Interface = 1024, // 0x00000400 接口Parameter = 2048, // 0x00000800 方法的參數(shù)Delegate = 4096, // 0x00001000 委托ReturnValue = 8192, // 0x00002000 返回值GenericParameter = 16384, // 0x00004000 泛型參數(shù)All = GenericParameter | ReturnValue | Delegate | Parameter | Interface | Event | Field | Property | Method | Constructor | Enum | Struct | Class | Module | Assembly, // 0x00007FFF ,所有 }

我們常用的限制是ALL或者類等,限制也可以是多個(gè),寫(xiě)法如下:限制A|限制B|限制C,表示A、B、C三種限制共存。具體原理是因?yàn)?AttributeTargets 是支持位運(yùn)算的枚舉,通過(guò)一定的位運(yùn)算可以在一個(gè)值中間存放多個(gè)枚舉。

說(shuō)了這么多,我們自己重新寫(xiě)一個(gè)特性類吧:

1.限定只能給類使用的特性

[AttributeUsage(AttributeTargets.Class)] public class DemoAttribute : Attribute { }

2.限定只能給方法使用的特性

[AttributeUsage(AttributeTargets.Method)] public class DemoAttribute : Attribute { }

3.限定不能繼承的特性

[AttributeUsage(AttributeTargets.All, Inherited = false)] public class DemoAttribute : Attribute { }

4.限定類和枚舉可以使用,但不能繼承的 特性

[AttributeUsage(AttributeTargets.Class| AttributeTargets.Enum, Inherited = false)] public class DemoAttribute : Attribute { }

需要注意的一點(diǎn)就是,如果要指定是否可以被繼承或者是否允許多次使用 這兩個(gè)屬性則需要先指定特性的作用范圍,即限定是類能使用還是所有都可以。

1.2 使用特性

我們自定義了一個(gè)特性,就必須使用它才能會(huì)有意義,否則它只是一個(gè)普通的類。那么我們?cè)撊绾问褂媚?#xff1f;其實(shí)在上一節(jié)中我們隱晦的介紹了特性的使用方式。就是用中括號(hào)包裹起來(lái),給類、屬性、方法等標(biāo)記起來(lái)。

首先我們定義一個(gè)賊普通的特性:

public class DemoAttribute : Attribute { }//沒(méi)有任何限制,可以用在任何支持特性的地方

然后使用它:

[Demo]//[DemoAttribute] public class TestDemo { }

如示例所示,在類上面添加[Demo]標(biāo)記,表示這個(gè)類應(yīng)用了特性DemoAttribute,也可以使用類名,但是C#會(huì)自動(dòng)忽略類名中結(jié)尾的Attribute。當(dāng)然有的人會(huì)把特性寫(xiě)在類或者方法等聲明的同一行開(kāi)頭位置,不過(guò)我一般會(huì)寫(xiě)在不同行,畢竟閱讀上簡(jiǎn)單明了。

我們之前說(shuō)過(guò),拋開(kāi)它集成自Attribute類不提,它也是一個(gè)類。既然是類,那么就會(huì)有屬性。那么現(xiàn)在定義一個(gè)帶屬性的特性類:

[AttributeUsage(AttributeTargets.Class| AttributeTargets.Enum, Inherited = false)] public class DemoAttribute : Attribute {public string Name { get; set; } }

該特性聲明了一個(gè)變量,使用方式如下:

[Demo(Name = "測(cè)試")] public class Student{ }

DemoAttribute是一個(gè)只能用在 類、枚舉 上的特性,有一個(gè)屬性是Name。在使用的時(shí)候可以用(屬性名="屬性值")的方式為屬性賦值。

更多的使用方式:

[AttributeUsage(AttributeTargets.Class| AttributeTargets.Enum, Inherited = false)] public class DemoAttribute : Attribute {public string Name { get; set; }public int Age { get; set; }public DemoAttribute(int age){Age = age;} }

使用:

[Demo(10,Name = "測(cè)試")] public Student(){ }

如果特性類聲明了構(gòu)造方法,那么在使用的時(shí)候,優(yōu)先按照構(gòu)造方法的順序進(jìn)行賦值,然后使用屬性名=屬性值的方式為其他屬性進(jìn)行賦值。

2. 特性在反射中的應(yīng)用

在第一節(jié)中介紹了如何聲明一個(gè)特性和使用特性,但是沒(méi)有反射或者類加載技術(shù),那么特性的作用就并沒(méi)有想象中的那么大。就像人有多個(gè)身份,但是也得有對(duì)應(yīng)的公司或者對(duì)應(yīng)的環(huán)境。比如說(shuō),王XX有個(gè)身份是某XX公司老總,那么XX公司得需要在工商局注冊(cè)登記,他這個(gè)身份才會(huì)有效。如果沒(méi)有登記,那么這個(gè)身份也就是個(gè)虛名。當(dāng)特性離開(kāi)了反射,離開(kāi)了類加載技術(shù),特性就是擺設(shè)。當(dāng)然這部分只限于自定義特性,因?yàn)镃#內(nèi)置的一些特性涉及到另外的技術(shù):動(dòng)態(tài)編譯,或者需要編譯器的配合。我們自定義的特性顯然沒(méi)有這些特權(quán),所以必須我們手動(dòng)開(kāi)發(fā)對(duì)應(yīng)的行為和規(guī)范。

首先,聲明一個(gè)類和特性:

[AttributeUsage(AttributeTargets.Class| AttributeTargets.Enum, Inherited = false)] public class DemoAttribute : Attribute {public string Name { get; set; }public int Age { get; set; }public DemoAttribute(int age){Age = age;} } [Demo(10,Name = "測(cè)試")] public class Student { }

2.1 獲取類的特性

var stuType = typeof(Student);

上述代碼先獲取到一個(gè)類的類型對(duì)象,然后調(diào)用:

IEnumerable<CustomAttributeData> attrs = stuType.CustomAttributes;

將獲取到這個(gè)類上聲明的所有的自定義的特性,不過(guò)獲取到的是一個(gè)CustomAttributeData,這個(gè)類封裝了一個(gè)特性的特征,但是在我們使用起來(lái)會(huì)很困難,而且我們更多的需要得到特性本身的對(duì)象,而不是這種需要我們進(jìn)一步處理的對(duì)象。那么,調(diào)用:

IEnumerable<Attribute> data = stuType.GetCustomAttributes(typeof(DemoAttribute));

通過(guò)上述方法就可以獲取到一組類型是DemoAttribute的特性對(duì)象。

那么回想一下為什么是一組?在AttributeUsageAttribute有一個(gè)AllowMultiple屬性,這個(gè)屬性就是用來(lái)標(biāo)記這個(gè)特性是否可以標(biāo)注多個(gè),也就是在同一目標(biāo)上多次使用,如果這個(gè)值為T(mén)rue,則在此處將獲取不定個(gè),否則最多一個(gè)。具體取決于對(duì)目標(biāo)做了多少標(biāo)記。

獲取到特性之后,依據(jù)實(shí)際需求進(jìn)行開(kāi)發(fā)。這里就不做過(guò)多介紹了,在后續(xù)篇幅中會(huì)對(duì)這部分的使用做更多的介紹。

2.2 獲取其他元素的特性

特性不止可以標(biāo)記在類上,還可以標(biāo)記在屬性、方法上。那么這些元素應(yīng)該如何獲取對(duì)應(yīng)的特性呢?

1. 屬性

var stuType = typeof(Student); var property = stuType.GetProperties()[0];//假設(shè)類有一個(gè)Property var attrs = property.GetCustomAttributes(typeof(DemoAttribute));

2. 方法

var stuType = typeof(Student); var method = stuType.GetMethods()[0];// 假設(shè)類有一個(gè)方法 var attrs = method.GetCustomAttributes(typeof(DemoAttribute));

需要注意的地方是,var 關(guān)鍵字;DemoAttribute只是一個(gè)代指,不是特指之前聲明的DemoAttribute特性類,因?yàn)橹奥暶鞯奶匦灶悰](méi)有對(duì)屬性和方法進(jìn)行支持,所以在本節(jié)中直接使用會(huì)編譯不通過(guò)。

特性就先簡(jiǎn)單的介紹到這里,特性可以標(biāo)記給很多目標(biāo)比如程序集、模塊、類等一系列,但實(shí)際開(kāi)發(fā)至少是Web開(kāi)發(fā)中,更多的是標(biāo)記類、方法、屬性等。這里只是介紹了特性的聲明和使用,但是沒(méi)有介紹實(shí)際開(kāi)發(fā)中特性的使用,這部分有機(jī)會(huì)在后續(xù)篇幅中介紹吧。因?yàn)槲乙灿玫牟皇呛芏唷?/p>

3. 反射中的泛型

之前在《C# 基礎(chǔ)知識(shí)系列- 5 泛型和反射》介紹過(guò),C#的泛型不會(huì)在編譯過(guò)程中抹去痕跡,意思就是我們可以通過(guò)反射獲取到對(duì)象的實(shí)際泛型類型。那么如何獲取呢?

var stuType = typeof(Student); // 獲取類的泛型參數(shù) var genericTypes = stuType.GenericTypeArguments;var method = stuType.GetMethods()[0]; // 獲取方法的泛型參數(shù) var types = method.GetGenericArguments();

這個(gè)問(wèn)題,在我寫(xiě)Java代碼的時(shí)候,困擾了我很久,沒(méi)有很好的辦法。但是在C#中,我可以不用考慮這個(gè)問(wèn)題。

4. 總結(jié)

反射在各大編程語(yǔ)言中是一個(gè)很重要的特點(diǎn),泛型、特性在泛型中扮演著很重要的角色。反射在實(shí)際開(kāi)發(fā)中扮演著很重要的角色,但是我們?cè)陂_(kāi)發(fā)中必須慎重考慮反射的使用。

到目前為止,反射介紹告一段落,但這不是結(jié)束。因?yàn)榉瓷涫莻€(gè)可深可淺的內(nèi)容,目前只是介紹了依稀概念和理論上的一些內(nèi)容,而更多的則隱藏在實(shí)際開(kāi)發(fā)中,這時(shí)候就需要結(jié)合需求進(jìn)行設(shè)計(jì)和代碼編寫(xiě)了。

更多內(nèi)容煩請(qǐng)關(guān)注我的博客《高先生小屋》

總結(jié)

以上是生活随笔為你收集整理的android 集成同一interface不同泛型_C# 基础知识系列- 10 反射和泛型(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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

主站蜘蛛池模板: 性欧美大战久久久久久久 | 成人观看 | 亚洲精品一区二区三区四区 | 亚洲综合在线中文字幕 | 白丝女仆被免费网站 | 成人黄色av网站 | 亚洲1234区| 夜夜嗨av禁果av粉嫩av懂色av | 亚洲影视在线 | 欧美一区二区三区大屁股撅起来 | 国产福利网 | 张柏芝亚洲一区二区三区 | 女女百合高h喷汁呻吟玩具 www.亚洲一区 | 国产人妻一区二区 | 在线观看欧美亚洲 | 91网站免费看| 久久无码人妻一区二区三区 | 奇米在线视频 | 亚洲网站在线 | 国产剧情av引诱维修工 | 伊人网久久久 | 色欧洲| 男人天堂新地址 | av新天堂| 激情开心成人网 | 国产日韩中文 | 91大神小宝寻花在线观看 | 羞羞色视频 | 亚洲av永久一区二区三区蜜桃 | 欧美精品一二三区 | 国产在线播放一区二区三区 | www.国产在线视频 | 中文字幕中文在线 | 朝鲜黄色片 | 生活片av| 国产精品第72页 | 台湾佬成人中文网222vvv | 国产精品无码在线 | 女性女同性aⅴ免费观女性恋 | 国产高清自拍av | 中国女人特级毛片 | 国模一区二区 | 成人免费高清在线播放 | 极品少妇网站 | 亚洲激情自拍偷拍 | 国产色区 | 奶水旺盛的少妇在线播放 | 91久久国产综合久久 | 91好色先生tv| 日本伦理中文字幕 | 亚洲精品观看 | 欧美激情自拍 | 国产黄色片在线播放 | 黄色av网站免费看 | 性感美女视频一二三 | 天堂av资源在线 | 婷婷调教口舌奴ⅴk | 亚洲最大福利视频 | 亚洲欧洲日本在线 | 黄黄视频在线观看 | 久久精品99国产精品日本 | 中文字幕一区二区三区乱码人妻 | 午夜精品视频 | 精品区一区二区 | 亚洲免费av网址 | 波多野结衣理论片 | 桃谷绘里香在线观看 | 亚洲国产精品久久 | 夜夜春夜夜爽 | 国产男同gay网站 | 女同毛片一区二区三区 | 久久久久久久久久久影院 | 天堂av官网 | av资源导航 | 蜜桃成人在线视频 | 四虎影库在线播放 | 久操视频在线观看免费 | 激情小说视频在线 | 亚洲熟女乱色综合亚洲av | 日韩高清一二三区 | 在线播放黄色网址 | 午夜看黄神器 | 精品一区av | 人妻洗澡被强公日日澡电影 | 日本妈妈9 | 毛片大全 | 好吊色一区二区三区 | 免费观看一级一片 | 夜夜嗨av一区二区三区四区 | 婷婷综合色 | 国产老熟女伦老熟妇露脸 | 亚州国产| 99久久亚洲精品 | 二区欧美| 日韩人妻一区二区三区蜜桃视频 | 精品久久久久久久久久久久久久 | 爱情岛论坛亚洲品质自拍视频 | 丝袜美腿亚洲一区二区图片 | 色婷婷综合久久久久中文字幕 |