這篇文章主要介紹了.net中泛型的概述與分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括竹山網(wǎng)站建設(shè)、竹山網(wǎng)站制作、竹山網(wǎng)頁(yè)制作以及竹山網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,竹山網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶(hù)以成都為中心已經(jīng)輻射到竹山省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶(hù)的支持與信任!泛型類(lèi)和泛型方法兼復(fù)用性、類(lèi)型安全和高效率于一身,是與之對(duì)應(yīng)的非泛型的類(lèi)和方法所不及。泛型廣泛用于容器(collections)和對(duì)容器操作的方法中。.NET Framework 2.0的類(lèi)庫(kù)提供一個(gè)新的命名空間System.Collections.Generic,其中包含了一些新的基于泛型的容器類(lèi)。
泛型的可變類(lèi)型參數(shù):通常用T,但也可以用任意非關(guān)鍵字和保留字;
所有的可變類(lèi)型T在編譯時(shí),都采用占位符的形式,在運(yùn)行時(shí)將由實(shí)際傳入的類(lèi)型來(lái)替換的所有的點(diǎn)位符;
針對(duì)早期版本的通用語(yǔ)言運(yùn)行時(shí)和C#語(yǔ)言的局限,泛型提供了一個(gè)解決方案。以前類(lèi)型的泛化(generalization)是靠類(lèi)型與全局基類(lèi)System.Object的相互轉(zhuǎn)換來(lái)實(shí)現(xiàn)。 .NET Framework 基礎(chǔ)類(lèi)庫(kù)的ArrayList容器類(lèi),就是這種局限的一個(gè)例子。ArrayList是一個(gè)很方便的容器類(lèi),使用中無(wú)需更改就可以存儲(chǔ)任何引用類(lèi)型或值類(lèi)型。
ArrayList list = new ArrayList(); double sum = 0; |
缺點(diǎn):
便利是有代價(jià)的,這需要把任何一個(gè)加入ArrayList的引用類(lèi)型或值類(lèi)型都隱式地向上轉(zhuǎn)換成System.Object。如果這些元素是值類(lèi)型,那么當(dāng)加入到列表中時(shí),它們必須被裝箱;當(dāng)重新取回它們時(shí),要拆箱。類(lèi)型轉(zhuǎn)換和裝箱、拆箱的操作都降低了性能;在必須迭代(iterate)大容器的情況下,裝箱和拆箱的影響可能十分顯著。另一個(gè)局限是缺乏編譯時(shí)的類(lèi)型檢查,當(dāng)一個(gè)ArrayList把任何類(lèi)型都轉(zhuǎn)換為Object,就無(wú)法在編譯時(shí)預(yù)防客戶(hù)代碼中類(lèi)似sum+=vlaue這樣的錯(cuò)誤;
在System.Collections.Generic命名空間中的泛型List
List double sum = 0; |
與ArrayList相比,在客戶(hù)代碼中唯一增加的List
泛型類(lèi)型或泛型方法的定義中,類(lèi)型參數(shù)是一個(gè)占位符(placeholder),通常為一個(gè)大寫(xiě)字母(也可以使用任意非關(guān)鍵字和保留字的名字),如T。在客戶(hù)代碼聲明、實(shí)例化該類(lèi)型的變量時(shí),把T替換為客戶(hù)代碼所指定的數(shù)據(jù)類(lèi)型。泛型類(lèi),如泛型中給出的List
List |
泛型提供了下列五種約束:
約束 | 描述 |
where T : struct | 參數(shù)類(lèi)型必須為值類(lèi)型 |
where T : class | 參數(shù)類(lèi)型必須為引用類(lèi)型 |
where T : new() | 參數(shù)類(lèi)型必須有一個(gè)公有的無(wú)參構(gòu)造函數(shù)。當(dāng)與其它約束聯(lián)合使用時(shí),new()約束必須放在最后。 |
where T : | 參數(shù)類(lèi)型必須為指定的基類(lèi)型或派生自指定基類(lèi)型的子類(lèi) |
where T : | 參數(shù)類(lèi)型必須為指定的接口或指定接口的實(shí)現(xiàn)??芍付ǘ鄠€(gè)接口的約束。接口約束也可以是泛型的。 |
無(wú)限制類(lèi)型參數(shù):
不能使用!=和==對(duì)可變類(lèi)型的實(shí)例進(jìn)行比較,因?yàn)闊o(wú)法保證具體的類(lèi)型參數(shù)支持這些運(yùn)算符;
它們可以與System.Object相互轉(zhuǎn)換,也可顯式地轉(zhuǎn)換成任何接口類(lèi)型;
可以與null比較。如果一個(gè)無(wú)限制類(lèi)型參數(shù)與null比較,當(dāng)此類(lèi)型參數(shù)為值類(lèi)型時(shí),比較的結(jié)果總為false。
無(wú)類(lèi)型約束:當(dāng)約束是一個(gè)泛型類(lèi)型參數(shù)時(shí),它就叫無(wú)類(lèi)型約束(Naked type constraints)。
class List |
在上面的示例中, Add方法的上下文中的T,就是一個(gè)無(wú)類(lèi)型約束;而List類(lèi)的上下文中的T,則是一個(gè)無(wú)限制類(lèi)型參數(shù)。
無(wú)類(lèi)型約束也可以用在泛型類(lèi)的定義中。注意,無(wú)類(lèi)型約束一定也要和其它類(lèi)型參數(shù)一起在尖括號(hào)中聲明:
//naked type constraint
public class MyClass
因?yàn)榫幾g器只認(rèn)為無(wú)類(lèi)型約束是從System.Object繼承而來(lái),所以帶有無(wú)類(lèi)型約束的泛型類(lèi)的用途十分有限。當(dāng)你希望強(qiáng)制兩個(gè)類(lèi)型參數(shù)具有繼承關(guān)系時(shí),可對(duì)泛型類(lèi)使用無(wú)類(lèi)型約束。
泛型類(lèi)封裝了不針對(duì)任何特定數(shù)據(jù)類(lèi)型的操作。泛型類(lèi)常用于容器類(lèi),如鏈表、哈希表、棧、隊(duì)列、樹(shù)等等。這些類(lèi)中的操作,如對(duì)容器添加、刪除元素,不論所存儲(chǔ)的數(shù)據(jù)是何種類(lèi)型,都執(zhí)行幾乎同樣的操作。
通常,從一個(gè)已有的具體類(lèi)來(lái)創(chuàng)建泛型類(lèi),并每次把一個(gè)類(lèi)型改為類(lèi)型參數(shù),直至達(dá)到一般性和可用性的最佳平衡。當(dāng)創(chuàng)建你自己的泛型類(lèi)時(shí),需要重點(diǎn)考慮的事項(xiàng)有:
哪些類(lèi)型應(yīng)泛化為類(lèi)型參數(shù)。一般的規(guī)律是,用參數(shù)表示的類(lèi)型越多,代碼的靈活性和復(fù)用性也就越大。過(guò)多的泛化會(huì)導(dǎo)致代碼難以被其它的開(kāi)發(fā)人員理解。
如果有約束,那么類(lèi)型參數(shù)需要什么樣約束。一個(gè)良好的習(xí)慣是,盡可能使用大的約束,同時(shí)保證可以處理所有需要處理的類(lèi)型。例如,如果你知道你的泛型類(lèi)只打算使用引用類(lèi)型,那么就應(yīng)用這個(gè)類(lèi)的約束。這樣可以防止無(wú)意中使用值類(lèi)型,同時(shí)可以對(duì)T使用as運(yùn)算符,并且檢查空引用;
把泛型行為放在基類(lèi)中還是子類(lèi)中。泛型類(lèi)可以做基類(lèi)。同樣非泛型類(lèi)的設(shè)計(jì)中也應(yīng)考慮這一點(diǎn)。泛型基類(lèi)的繼承規(guī)則;
是否實(shí)現(xiàn)一個(gè)或多個(gè)泛型接口。例如,要設(shè)計(jì)一個(gè)在基于泛型的容器中創(chuàng)建元素的類(lèi),可能需要實(shí)現(xiàn)類(lèi)似IComparable
對(duì)于一個(gè)泛型類(lèi)Node
// concrete type |
非泛型的具體類(lèi)可以繼承自封閉構(gòu)造基類(lèi),但不能繼承自開(kāi)放構(gòu)造基類(lèi)。這是因?yàn)榭蛻?hù)代碼無(wú)法提供基類(lèi)所需的類(lèi)型參數(shù):
//No error. |
泛型的具體類(lèi)可以繼承自開(kāi)放構(gòu)造類(lèi)型。除了與子類(lèi)共用的類(lèi)型參數(shù)外,必須為所有的類(lèi)型參數(shù)指定類(lèi)型:
//Generates an error. |
繼承自開(kāi)放結(jié)構(gòu)類(lèi)型的泛型類(lèi),必須指定參數(shù)類(lèi)型和約束:
class NodeItem |
泛型類(lèi)型可以使用多種類(lèi)型參數(shù)和約束:
class KeyType |
開(kāi)放結(jié)構(gòu)和封閉構(gòu)造類(lèi)型可以用作方法的參數(shù):
void Swap |
當(dāng)一個(gè)接口被指定為類(lèi)型參數(shù)的約束時(shí),只有實(shí)現(xiàn)該接口的類(lèi)型可被用作類(lèi)型參數(shù)。
可以在一個(gè)類(lèi)型指定多個(gè)接口作為約束,如下:
class Stack |
一個(gè)接口可以定義多個(gè)類(lèi)型參數(shù),如下:
IDictionary |
接口和類(lèi)的繼承規(guī)則相同:
//Okay. |
具體類(lèi)可以實(shí)現(xiàn)封閉構(gòu)造接口,如下:
class MyClass : IBaseInterface |
泛型類(lèi)可以實(shí)現(xiàn)泛型接口或封閉構(gòu)造接口,只要類(lèi)的參數(shù)列表提供了接口需要的所有參數(shù),如下:
//Okay. |
泛型類(lèi)、泛型結(jié)構(gòu),泛型接口都具有同樣方法重載的規(guī)則。
泛型方法是聲名了類(lèi)型參數(shù)的方法,如下:
void Swap |
下面的示例代碼顯示了一個(gè)以int作為類(lèi)型參數(shù),來(lái)調(diào)用方法的例子:
int a = 1; |
也可以忽略類(lèi)型參數(shù),編譯器會(huì)去推斷它。下面調(diào)用Swap的代碼與上面的例子等價(jià):
Swap(a, b); |
靜態(tài)方法和實(shí)例方法有著同樣的類(lèi)型推斷規(guī)則。編譯器能夠根據(jù)傳入的方法參數(shù)來(lái)推斷類(lèi)型參數(shù);而無(wú)法單獨(dú)根據(jù)約束或返回值來(lái)判斷。因此類(lèi)型推斷對(duì)沒(méi)有參數(shù)的方法是無(wú)效的。類(lèi)型推斷發(fā)生在編譯的時(shí)候,且在編譯器解析重載方法標(biāo)志之前。編譯器對(duì)所有同名的泛型方法應(yīng)用類(lèi)型推斷邏輯。在決定(resolution)重載的階段,編譯器只包含那些類(lèi)型推斷成功的泛型類(lèi)。
在泛型類(lèi)中,非泛型方法能訪問(wèn)所在類(lèi)中的類(lèi)型參數(shù):
class List |
在泛型類(lèi)中,定義一個(gè)泛型方法,和其所在的類(lèi)具有相同的類(lèi)型參數(shù);試圖這樣做,編譯器會(huì)產(chǎn)生警告CS0693。
class List warning CS0693: 類(lèi)型參數(shù)“T”與外部類(lèi)型“List |
在泛型類(lèi)中,定義一個(gè)泛型方法,可定義一個(gè)泛型類(lèi)中未定義的類(lèi)型參數(shù):(不常用,一般配合約束使用)
class List void Add(List items) where U : T{} //常用 |
泛型方法通過(guò)多個(gè)類(lèi)型參數(shù)來(lái)重載。例如,下面的這些方法可以放在同一個(gè)類(lèi)中:
void DoSomething() { } |
在泛型類(lèi)和泛型方法中會(huì)出現(xiàn)的一個(gè)問(wèn)題是,如何把缺省值賦給參數(shù)化類(lèi)型,此時(shí)無(wú)法預(yù)先知道以下兩點(diǎn):
T將是值類(lèi)型還是引用類(lèi)型
如果T是值類(lèi)型,那么T將是數(shù)值還是結(jié)構(gòu)
對(duì)于一個(gè)參數(shù)化類(lèi)型T的變量t,僅當(dāng)T是引用類(lèi)型時(shí),t = null語(yǔ)句才是合法的; t = 0只對(duì)數(shù)值的有效,而對(duì)結(jié)構(gòu)則不行。這個(gè)問(wèn)題的解決辦法是用default關(guān)鍵字,它對(duì)引用類(lèi)型返回空,對(duì)值類(lèi)型的數(shù)值型返回零。而對(duì)于結(jié)構(gòu),它將返回結(jié)構(gòu)每個(gè)成員,并根據(jù)成員是值類(lèi)型還是引用類(lèi)型,返回零或空。
class GenericClass { T GetElement() { return default(T); } } |
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“.net中泛型的概述與分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司,關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、網(wǎng)站設(shè)計(jì)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿(mǎn)足用戶(hù)豐富、多元化的應(yīng)用場(chǎng)景需求。