泛型與集合型別

2021-07-09 21:01:32 字數 3800 閱讀 6351

說起泛型時,

就不得不說到泛型集合型別

,因為使用反省能夠極大的提高集合型別的效能和安全性.

為了看看使用泛型能為集合型別帶來什麼好處,

先看看不用泛型時集合型別的表現

.最典型的非泛型集合型別就是

arraylist了,

這裡便以它為例作為介紹

,考慮一下下面的**:

arraylist list = new arraylist();

const int listsize = 3;

for (int i = 0; i < listsize; i++)

for (int i = 0; i < listsize; i++)

如果對.net

的型別系統沒有深刻的認識

,可能會覺得上面的**沒有任何的問題

,樓主一開始就覺得沒問題

.實際上

,上面的**屬於典型的」可以執行」的**,

而非」好的」**.

因為arraylist

型別為了包容任何型別

,所以他接受的引數為所有型別的基類

object,object

是乙個引用型別,而

int是乙個值型別

,因此當呼叫

list.add()時,

存在乙個裝箱操作.同理

,當從arraylist

中獲得元素時

,又需要乙個拆箱操作

:int value=(int)list[i].

這兩個操作對於

.net

來說是相當耗時的

,尤其是當集合型別包含的元素比較多或值型別比較大

(比如複雜的列舉或者結構

)的時候

.

如果現在對裝箱和拆箱還沒有太深的理解

,可以回頭看看前面講解的東西.

通過使用泛型,

由於集合中的元素型別在編譯時已經確定

,就避免了拆裝箱的操作

,這樣便顯著提高了集合型別的效能.在

.net中,

與arraylist

作用相同的泛型型別是

list,

這裡有乙個小小的測試

:

class program

private static void userarraylist()

for (int i = 0; i < listsize; i++)

long endticks = datetime.now.ticks;

console.writeline("使用arraylist,耗時: ticks",endticks-startticks);

}private static void usergenericlist()

for (int i = 0; i < listsize; i++)

long endticks = datetime.now.ticks;

console.writeline("使用list,耗時: ticks",endticks-startticks);

} }

機器的配置可能不同,

輸出的結果差別可能很大

,如果你的機器的配置比較高

,可能兩個輸出都是

0,此時你需要增大一下

listsize的值,

但是不管怎樣,使用

list

比使用arraylist

提高了差不多

2倍的效能

.當使用乙個大的值型別時

,比如列舉或者結構

,獲得差異還會更大

.

泛型能夠提高的另乙個好處就是型別安全,

這時啥意思

?看一段**:

arraylist list = new arraylist();

int i = 100;

list.add(i);

string value = (string)list[0];

因為型別不匹配,

所以這段**有問題

,新增到

arraylist

中的是乙個

int型別

,而獲取時卻想將它轉換為

string型別.

可惜的是

,編譯器無法知道

,因為對它來說

,不管是

int也好

,string也好,

他們都是

object型別.

在編譯**時

,編譯器提供給開發者的最大幫助之一就是可以檢查出錯誤

,也就是常說的編譯時錯誤

(compile time error),.

當使用arraylist

的時候,

對於上面的問題沒變異起無能為力

,因為他認為這是合法的

,編譯可以順利通過

.這種錯誤有時候隱藏在程式中很難發現

,最糟糕的情況是產品已經交付給使用者了

,而當使用者在使用時不巧的執行到這段**

,變回丟擲乙個異常

,這時的錯誤

,成為執行時錯誤

(runtime error).

通過使用泛型集合,

這種情況將不復存在

,當試圖進行類似上面的轉換時

,根本無法通過編譯

,這樣有助於今早的發現問題:

listlist = new list();

int i = 100;

list.add(i);

string value = (string)list[0];//這裡會出現編譯錯誤

最後給大家說乙個使用泛型的小技巧.

當程式大量使用泛型型別的時候

,或者泛型的型別引數個數比較多的時候

,**可能看著比較散亂

,不夠簡潔

.此時可以使用

using

指令來宣告乙個代表著泛型型別的集合:

using intlist = list;//一定要寫到程式的第一行

class program

}

這樣看上去簡單多了,

但是還有乙個問題

,就是不能跨檔案使用

,換而言之

,在同一專案統一命名空間下的另乙個檔案中

,無法使用這個

intlist集合.

此時,可以採用繼承泛型型別的方式來解決

,例如宣告下面這樣乙個類

:

public class intlist:list{}

這個類不包含任何的實現,

它的所有能力都繼承自

list,

這樣在多個檔案中

,都可以使用

intlist,

它的使用方式和

list

沒有區別

,只是看起來更加簡潔一些

.

泛型是個很重要的知識,

泛型可以避免重複**

,還學習了如何使用型別引數約束以及泛型方法

,通過泛型集合

list

與非泛型結合

arraylist

的對比,

了解了反省在集合型別中的應用和優勢

.

泛型集合,非泛型集合

arraylist 非泛型集合 list 泛型集合 集合跟陣列比較我們更容易理解。陣列 1,長度固定2,資料型別預先宣告 集合 1,長度可變2,資料型別預先宣告的為泛型集合,資料型別不限定為非泛型 arraylist 長度不固定,元素資料型別為object的集合。object類之間或間接為所有類的父...

c 集合與泛型集合

集合的命名空間 using system.collections 泛型的命名空間 using system.collections.generic 命名空間包含定義泛型集合的介面和類,泛型集合允許使用者建立強型別集合,它能提供比泛型集合更好的型別安全性和效能。集合的事例 arraylist list...

C 集合與泛型集合

看到這個標題,大家應該就知道有泛型集合,就有非泛型集合 既然都是集合,咱們今兒就簡單的來對比講解下 需要記住的不算太多,理解記憶 理解記憶 2017 11 0411 39 09 c 泛型集合之非泛型集合類與泛型集合類的對應 arraylist對應list hashtable對應dictionary ...