說起泛型時,
就不得不說到泛型集合型別
,因為使用反省能夠極大的提高集合型別的效能和安全性.
為了看看使用泛型能為集合型別帶來什麼好處,
先看看不用泛型時集合型別的表現
.最典型的非泛型集合型別就是
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 ...