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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第十二章 泛型

發(fā)布時間:2023/12/2 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第十二章 泛型 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄:

12.1 FCL中的泛型

12.2 泛型基礎(chǔ)結(jié)構(gòu)

12.3 泛型接口

12.4 泛型委托

12.5 委托和接口的逆變和協(xié)變泛型類型實(shí)參

12.6 泛型方法

12.7 泛型和其他成員

12.8 可驗(yàn)證性和約束

?

泛型時CLR和編程語言提供的一種特殊機(jī)制,它支持另一種形式的代碼重用,即“算法重用”。

大多數(shù)算法允許都封裝在一個類型中,CLR允許創(chuàng)建泛型引用類型和泛型值類型,但不允許創(chuàng)建泛型枚舉類型。CLR還允許創(chuàng)建泛型接口和泛型委托。方法偶爾也封裝有用的算法,所以CLR允許在引用類型,值類型或接口中定義泛型方法。

定義泛型類型或方法時,為類型指定的任何變量(比如T)都稱為類型參數(shù)。T是變量名,源代碼能使用數(shù)據(jù)類型的任何地方都能使用T。

使用泛型類型或方法時指定的具體數(shù)據(jù)類型稱為類型實(shí)參。

優(yōu)勢:

源代碼保護(hù):使用泛型算法的開發(fā)人員不需要訪問算法的源代碼。

類型安全:將泛型算法應(yīng)用于一個具體的類型時,編譯器和CLR能理解開發(fā)人員的意圖,并保證只有與指定數(shù)據(jù)類型兼容的對象才能用于算法。

更清晰的代碼:由于編譯器強(qiáng)制類型安全性,所以減少了源代碼中必須進(jìn)行的強(qiáng)制類型轉(zhuǎn)換次數(shù),使代碼易于編寫和維護(hù)。

更佳的性能:CLR不需要執(zhí)行裝箱操作,值類型的實(shí)例以傳值的方式傳遞。

12.1 FCL中的泛型

泛型最明顯的應(yīng)用就是集合類。集合類型實(shí)現(xiàn)了許多接口,放入集合中的對象可實(shí)現(xiàn)接口來執(zhí)行排序和搜索等操作。

12.2 泛型基礎(chǔ)結(jié)構(gòu)

CLR添加泛型需要的工作:

創(chuàng)建新的IL指令,使之能夠識別類型參數(shù)。

修改現(xiàn)有元數(shù)據(jù)表的格式,以便表示具有泛型參數(shù)的類型名稱和方法。

修改各種編程語言(C#,Microsoft Visual Basic .NET等)來支持新語法,允許開發(fā)人員定義和引用泛型類型和方法。

修改編譯器,使之能生成新的IL指令和修改的元數(shù)據(jù)格式。

修改JIT編譯器,以便處理新的支持類型實(shí)參的IL指令來生成正確的本機(jī)代碼。

創(chuàng)建新的反射成員,使開發(fā)人員能查詢類型和成員,以判斷它們是否具有泛型參數(shù)。另外,還必須定義新的反射成員,使開發(fā)人員能在運(yùn)行時創(chuàng)建泛型類型和方法定義。

修改調(diào)試器以顯示和操縱泛型類型,成員,字段以及局部變量。

修改VS的“智能感知”功能。將泛型類型或方法應(yīng)用于特性數(shù)據(jù)類型時能顯示成員的原型。

12.2.1 開放類型和封閉類型

具有泛型類型參數(shù)的類型成為開發(fā)類型,CLR禁止構(gòu)造開放類型的任何實(shí)例。這類似于CLR禁止構(gòu)造接口類型的實(shí)例。

代碼引用泛型類型時可指定一組泛型類型實(shí)參。為所有類型參數(shù)都傳遞了實(shí)際的數(shù)據(jù)類型,類型就成為封閉類型。CLR允許構(gòu)造封閉類型的實(shí)例。然而,代碼引用泛型類型的時候,可能留下一些泛型類型實(shí)參未指定。這會在CLR中創(chuàng)建新的開發(fā)類型對象,而且不能創(chuàng)建該類型的實(shí)例。

12.2.2 泛型類型和繼承

泛型類型仍然時類型,所以能從其他任何類型派生。使用泛型類型并指定類型實(shí)參時,實(shí)際是在CLR中定義一個新的類型對象,新的類型對象從泛型類型派生自的那個類型派生。

12.2.3 泛型類型同一性

12.2.4 代碼爆炸

使用泛型類型參數(shù)的方法在進(jìn)行JIT編譯時,CLR獲取方法的IL,用指定的類型實(shí)參替換,然后創(chuàng)建恰當(dāng)?shù)谋緳C(jī)代碼(這些代碼未操作指定數(shù)據(jù)類型“量身定制”)。缺點(diǎn):CLR要為每種不同的方法/類型組合生成本機(jī)代碼。這個現(xiàn)象時“代碼爆炸”。

CLR內(nèi)建了一些優(yōu)化措施能緩解代碼爆炸。假如為特定的類型實(shí)參調(diào)用了一個方法,以后再用相同的類型實(shí)參調(diào)用這個方法,CLR只會為這個方法/類型組合編譯一次代碼。

CLR還有另一優(yōu)化,它認(rèn)為所有引用類型實(shí)參都完全相同,所以代碼能夠共享。(所有引用類型的參數(shù)或變量實(shí)際上只是指向堆上對象的指針,所有對象指針都以相同方式操縱)

如果某個類型時值類型,CLR就必須專門為那個值類型生成本機(jī)代碼。因?yàn)橹殿愋偷拇笮〔欢?#xff0c;CLR無法共享代碼,因?yàn)榭赡芤貌煌谋緳C(jī)CPU指令來操縱這些值。

12.3 泛型接口

使用非泛型接口來操縱值類型會發(fā)生裝箱,而且會失去編譯時的類型安全性。更到內(nèi)容請參考在13章接口

12.4 泛型委托

CLR支持泛型委托,目的是保證任何類型的對象都能以類型安全的方式傳給回調(diào)函數(shù)。泛型委托允許值類型實(shí)例在傳給給回調(diào)方法時不進(jìn)行任何裝箱。?

12.5 委托和接口的逆變和協(xié)變泛型類型實(shí)參

委托的每個泛型類型參數(shù)都可標(biāo)記為協(xié)變量或逆變量。這樣就可將泛型委托類型的變量轉(zhuǎn)換為相同的委托類型(但泛型參數(shù)類型不同)。泛型類型參數(shù):

不變量:意味著泛型類型參數(shù)不能更改。

逆變量:意味著泛型類型參數(shù)可以從一個類更改為它的某個派生類。在C#中用in關(guān)鍵字標(biāo)記逆變量形式的泛型類型參數(shù)。逆變量泛型類型參數(shù)只出現(xiàn)在輸入位置,比如作為方法的參數(shù)。

協(xié)變量:意味著泛型類型參數(shù)可以從一個類更改為它的某個基類。C#是用out關(guān)鍵字標(biāo)記協(xié)變量形式的泛型類型參數(shù)。協(xié)變量泛型類型參數(shù)只能出現(xiàn)在輸出位置,比如作為方法的返回類型。

(協(xié)變性指定返回類型的兼容性,逆變性指定參數(shù)的兼容性)

對于泛型類型參數(shù),如果要將該類型的實(shí)參傳給使用out或ref關(guān)鍵的方法,便不允許可變性。

12.6 泛型方法

定義泛型類,結(jié)構(gòu)或方法時,類型中定義的任何地方都可引用類型指定的類型參數(shù)。類型參數(shù)可作為方法參數(shù),方法返回值或方法內(nèi)部定義的局部變量的類型使用。CLR也允許方法指定它自己的類型參數(shù)。這些參數(shù)也可以作為參數(shù),返回值,或局部變量使用。

泛型方法和類型推斷

C#編譯器支持在調(diào)用泛型方法時進(jìn)行類型推斷。這意味著編譯器會在調(diào)用泛型方法時自動推斷要使用的類型。

12.7 泛型和其他成員

在C#中,屬性,索引器,事件,操作符方法,構(gòu)造器和終結(jié)器本身不能有類型參數(shù)。但它們能在泛型類型中定義,而且這些成員中的代碼能使用類型的類型參數(shù)。

12.8 可驗(yàn)證性和約束

?約束機(jī)制:約束的作用是限制能指定成泛型實(shí)參的類型數(shù)量。通過限制類型的數(shù)量,可以對那些類型執(zhí)行更多操作。

約束可應(yīng)用于泛型類型的類型參數(shù),也可用于泛型方法的類型參數(shù)。CLR不允許基于類型參數(shù)名稱或約束來進(jìn)行重載;只能基于元數(shù)(類型參數(shù)個數(shù))對類型或方法進(jìn)行重載。

重寫虛泛型方法時,重寫的方法必須指定相同數(shù)量的類型參數(shù),而且這些類型參數(shù)繼承在基類方法上指定的約束。事實(shí)上,根本不允許為重寫方法的類型參數(shù)指定任何約束。但類型參數(shù)的名稱是可以改變的。類似地,實(shí)現(xiàn)接口方法時,方法必須指定與接口方法等量地類型參數(shù),這些類型參數(shù)將繼承由接口方法指定地約束。

12.8.1 主要約束

類型參數(shù)可以指定零個或者一個主要約束。主要約束可以代表非密封類地一個引用類型。

指定引用類型約束時,相當(dāng)于向編譯器承諾:一個指定的類型實(shí)參要么時與約束類型相同的類型,要么時從約束類型派生的類型。

12.8.2 次要約束

類型參數(shù)可以指定零個或者多個次要約束,次要約束代表接口類型。這種約束向編譯器承諾類型實(shí)參實(shí)現(xiàn)了接口。由于能指定多個接口約束,所以類型實(shí)參必須實(shí)現(xiàn)了所有接口約束。

還有一種次要約束稱為類型參數(shù)約束,有時也稱為裸類型約束。這種約束用得比接口約束少得多。它允許一個泛型類型或方法規(guī)定:指定的類型實(shí)參要么就是約束的類型,要么時約束的類型的派生類。一個類型參數(shù)可以指定零個或者多個類型參數(shù)約束。

12.8.3 構(gòu)造器約束

類型參數(shù)可指定零個或一個構(gòu)造器約束,它向編譯器承諾類型實(shí)參是是實(shí)現(xiàn)了公共無參構(gòu)造器的非抽象類型。where T : new()

12.8.4 其他可驗(yàn)證性問題

1.泛型類型變量的轉(zhuǎn)型

將泛型類型的變量轉(zhuǎn)型為其他類型是非法的,除非轉(zhuǎn)型為與約束兼容的類型。

2.將泛型類型變量設(shè)為默認(rèn)值

將泛型類型變量設(shè)為null是非法的,除非將泛型類型約束成引用類型。

3.將泛型類型變量與null進(jìn)行比較

無論泛型類型是否被約束,使用==或!=操作符將泛型類型變量與null進(jìn)行比較都是合法的。

4.兩個泛型類型變量相互比較

如果泛型類型參數(shù)不能肯定是引用類型,對同一個泛型類型的兩個變量進(jìn)行比較是非法的。

5.泛型類型變量作為操作數(shù)使用

將操作符應(yīng)用于泛型類型操作數(shù)會出現(xiàn)大量問題。不能將操作符應(yīng)用于泛型類型的變量。

?

轉(zhuǎn)載于:https://www.cnblogs.com/terry-1/p/10028569.html

總結(jié)

以上是生活随笔為你收集整理的第十二章 泛型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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