2016年7月12日 星期二

泛型 generic

好久好久以前,學習 C# 應該有聽過 ArrayList 這個類別。還蠻好用的,不僅僅可以把字串丟進去,數字也可以,自訂的類別也可以,甚至...你要混搭,混著丟也可以。

ArrayList al = new ArrayList();
al.Add("字串");
al.Add(66);
al.Add(new Student("1","paladin"));

如同上面的例子,似乎什麼樣的型別,都可以放進 ArrayList,主要是因為 ArrayList 把裡面所有的內容都包裝(Boxing)成「物件(Object)」型別了,換句話說,ArrayList 裡面放的,都是 Object 型別。像這樣的特性,我們又把他歸類為:非泛型集合(nongeneric collection)。可想而知,這種非泛型集合,雖然可以讓你隨性的把任何東西都丟進去,但當你要從裡面把資料取出來時,就不能保證拆解(Unboxing)時,裡面的型別是否就是你所預期的。當然,程式在編譯時,也不會幫你進行型別檢查,往往要等到程式執行時,才會出現所謂的 Run Time Error。聽起來,使用這個非泛型集合很像很「」,對不對?沒錯,所以我們會稱非泛型集合裡面的成員為「弱型別」(Weak Typing)。

既然有所謂的「弱」,自然就會有跟它相對應的「強」。強型別 (Strong Typing) 的特性,當然就具備了以下的特徵【Ref.01】:

1.所有的變數的資料型態,在編譯時都要被知道。
2.嚴格的落實資料型態必須相符規則。例如,字串不能轉成數字。
3.所有型別轉換的錯誤,會導致編譯錯誤。也就是說,型別錯誤就無法編譯成功。

強型別具備上述特徵,自然就有了下面的好處【Ref.02,03】:

1.讓 IntelliSense 能夠支援變數。這能讓您在輸入程式碼時看到變數的屬性及其他成員。
2.可以利用編譯器型別檢查,這能找出可能因錯誤 (例如溢位) 而在 Run Time 失敗的陳述式。這也能夠偵測在不支援變數的物件上所進行的方法呼叫。
3.執行程式碼的速度較快。

相對於非泛型集合的,就是泛型集合( generic collection )【Ref. 04】,而裡面所放的成員,則都是屬於強型別。這裡的代表人物 List,於是登場了。這個 T ,代表了某一種資料型別,可以是:int,string...或者是使用者自訂的一個類別。



參考:

01.What is strong-typing versus weak-typing? Which is preferred? Why?
02.Efficient Use of Data Types 
03.何謂「強型別」(Strong Type)
04.When to Use Generic Collections