有關泛型的用法

2021-09-06 00:15:54 字數 4024 閱讀 4264

泛型(generic)是對clr型別系統的擴充套件,用於定義未指定某些細節的型別。實際上,**本身就是泛型。

使用泛型可以避免以下兩個常見的問題:**冗餘和困擾開發人員的含混不清的編譯器錯誤。假設集合類sortedlist是object引用的集合,genericsortedlist是任意型別的集合,使用泛型具有以下明顯的優點。

(1)型別安全

當使用者向sortedlist型別的集合內新增string時,string會隱式強制轉換為object。同樣,如果從該列表中檢索string物件,則它必須在執行時從object引用強制轉換到string引用。這樣就會造成編譯時缺少型別安全,從而使編寫的**容易出錯。相反,如果使用genericsortedlist(t的型別被設定為string),就會使所有的新增和查詢方法是用string引用。這樣在編譯時就可以檢查元素的型別是否正確。

(2)二進位制**重用

為了進行維護,開發人員可以選擇使用sortedlist,通過從它派生sortedlistofstring來實現編譯時的型別安全。此方法有乙個問題,那就是必須對於每個需要型別安全列表的型別都編寫新**,而這會很快變成非常費力的工作。使用genericsortedlist,需要執行的全部操作就是將具有所需元素型別的型別例項化為t。泛型**還有乙個附加價值,那就是它在執行時生成,因此,對於無關元素型別的兩個擴充套件(如genericsortedlist和genericsortedlist)能夠重新使用同乙個實時(jit)編譯**的大部分。clr只是處理細節就可以了,從而使**不再臃腫。

(3)效能

如果能在編譯時進行型別檢查,而不是在執行時進行檢查,則顯然會大大增強系統的效能。在託管**中,引用和值之間的強制轉換既會導致裝箱又會導致拆箱,而且避免這樣的強制轉換可能會對效能產生同樣的負面影響。如果對乙個由一百萬個整數組成的陣列進行快速排序法基準測試,就會發現泛型方法比非泛型方法快得多。這是由於完全避免了對這些值進行裝箱。如果針對由字串引用組成的陣列進行同樣的排序,則由於無需在執行時執行型別檢查,因此使用泛型方法後大大提高了效能。

(4)清晰性

泛型的清晰性體現在許多方面。約束是泛型的乙個功能,它會禁止對泛型**進行不相容的擴充套件;使用泛型,也不再有困擾c++模板使用者的含混不清的編譯器錯誤。在genericsortedlist中,集合類將有乙個約束,該約束使集合類只處理可進行比較並依此進行排序的t型別。同樣,通常可以使用名為型別推理的功能來呼叫泛型的方法,而無需使用任何特殊語法。當然,編譯時型別安全可以使應用程式**更加清晰。

泛型的定義

clr支援多種程式語言,因此,clr泛型也有多種語法。但是,無論採用哪種語法,用一種面向clr的語言編寫的泛型**也可以由其他面向clr的語言編寫的程式使用。

泛型的定義**語法為:

[訪問修飾符] [返回型別] 泛型支援型別泛型名稱《型別引數列表》

其中,clr支援泛型類、結構、方法、介面和委託等。泛型名稱要符合標示符的定義。尖括號表示型別引數列表,尖括號緊跟在泛型類型別或成員的名稱後面。同樣,在型別引數列表中有乙個或多個型別引數,形式如。

例1:定義乙個泛型類

1

class

node

<

t>26

例2:定義乙個泛型方法

1

void

swap

<

t>

(ref

t item1,

reft item2)27

泛型的引用

引用泛型時,也可以將未指定的型別變成系統能夠識別的指定的型別。例3和例4分別是對例1和例2的引用示例。

例3:引用乙個泛型類

1

class

node8bit:node

<

byte

>25

例4:引用乙個泛型方法

1

decimal d1=0

,d2=2;

2swap

<

decimal

>

(ref

d1,ref

d2);

通過例子可以看出,定義乙個類或者方法時,可以利用泛型代表任何一種型別,而在引用時再指定具體型別。在例6中,當**呼叫泛型方法swap時,c#編譯器會自動將定義的泛型轉換為引用**中指定的型別,從而大大簡化了程式設計人員**書寫的工作量。

由於泛型可以代表任何一種型別,因此只定義一次方法的引數型別就能實現所有型別的引用。例如,例6中的d1可能是int型、float型等(d2同樣如此),如果不使用泛型,就需要寫出很多過載的swap方法,使**既臃腫,又不易閱讀,同時也增加了編譯工作量。由此可以看出,泛型的優點是顯而易見的。

常用的泛型集合

在.net framework類庫中,system.collections.generic和system.collections.objectmodel命名空間中提供了很多泛型集合類。許多泛型集合型別是泛型型別的直接模擬。表1列出了常見的泛型集合類與非泛型集合類的對應關係。

表1         常見的泛型集合類及對應的非泛型集合類

list泛型類表示可通過索引訪問的物件的強型別列表,提供用於對列表進行搜尋、排序和操作的方法。常用方法如下。

add方法:將指定值的元素新增到list<>中。

insert方法:在列表的中間插入乙個新元素。

contains方法:測試該列表中是否存在某個元素。

remove方法:從列表中移除帶有指定鍵的元素。

clear方法:移除列表中的所有元素。

2. dictionary

add方法:將帶有指定鍵和值的元素新增到dictionary中。

containskey方法:確定dictionary中移除帶有指定鍵的元素。

remove方法:從dictionary移除帶有指定鍵的元素。

3. queue

queue泛型類表示物件的先進先出集合。

常用方法如下:

enqueue方法:將指定元素插入列尾。

dequeue方法:佇列首元素出列。

4. stack

stack泛型類表示同一任意型別的例項的大小可變的後進先出(lifo)集合。

常用方法如下:

push方法:將指定元素插入棧項。

pop方法:將棧項元素彈出。

5. sortedlist

sortedlist泛型類表示鍵/值對的集合,這些鍵/值對基於關聯的icomparer實現按照鍵進行排序。

常用方法如下:

add方法:將帶有指定鍵和值的元素新增到sortedlist中。

containskey方法:確定sortedlist中是否包含指定的鍵。

remove方法:從sortedlist中移除帶有指定鍵的元素。

例5:現有乙個活期存款賬戶類account,為其提供處理業務的customers類有乙個方法createaccount(賬戶名,開戶金額),試使用sortedlist建立泛型物件,並判斷是否存在賬戶「張三」,若不存在,則建立賬戶;若存在,則為其追加存款。

主要**如下所示:

1

using

system;

2using

system.io;

3using

system.collections.generic;

4namespace

genricexample516

set1720}

21public

intaccountvalue

2227

set2831}

32}33public

class

customers

3441}42

class

porgram

4355

else

5661}62

}63}64

泛型萬用字元 的用法

泛型中提供了?萬用字元,可以引用其他各種引數化的引數,萬用字元定義的變數主要用作引用,可以呼叫與引數化無關的方法,不能呼叫與引數化有關的方法 具體可以看如下 public static void convert collection collection collection collection表...

泛型的高階用法

package t public class 泛型的高階用法 在泛型中使用萬用字元形式 listl1 new arraylist 例項化乙個arraylist物件 l1.add 成員 在集合中新增內容 list l2 l1 使用萬用字元 list l3 new linkedlist system.o...

泛型的方法用法

泛型還是很省 的,所以有必要學會!參考部落格 我實際中使用 1.無返回值方法 publicvoid sortaction list userlabellistvolist,listclassifynames listutils.sortbyclassifyrank userlabellistvoli...