摘要:Visual Basic 2005 - ArrayList 類別還是最佳選擇嗎?
我想是過去各方大力宣傳並鼓吹使用的結果,直到如今,我們發現許多朋友還是非常喜歡使用 ArrayList 類別。事實上在許多時候,ArrayList 類別已經不是最佳的選擇。
就功能性而言,.NET Framework 2.0 所推出的泛用集合類別 List 就是對應於非泛用集合類別 ArrayList。在此要提醒大家,在大多數的情況下,List 擁有較佳的效率而且是型別安全的。如果您將一個參考型別(Reference Type)傳遞給 List 的型別參數 T,則 List 與 ArrayList 的運作是完全相同的。然而,如果您將一個數值型別(Value Type)傳遞給型別參數 T,您就必須仔細評估實作與 boxing 議題。
您將一個數值型別傳遞給型別參數 T,編譯器會特別針對該數值型別產生 List 類別的一個實作。此意味著,List 物件中的項目在可以被使用之前並不需要加以 Box,在大約 500 個項目被建立之後,儲存未 box 項目的記憶體會大於用來產生此類別實作的記憶體。
使用泛用集合類別 List 的型別特定實作要優於使用 ArrayList 類別或是自行去撰寫一個強型別包裝集合。理由是您的實作必須去再做一次 .NET Framework 已經替您做好的事情,而且 CLR 能夠共用 Microsoft 中繼語言程式碼和中繼資料,而這是您的實作所做不到的。
我們之所以會建議使用泛用集合類別,主要原因就是您不需要衍生自一個基底集合型別並實作型別特定的成員就可以立即享有型別安全的好處。此外,當集合項目是數值型別(Value Type)的時候,也將因為不需要去 box 集合項目,而使得泛用集合類別在效率表現上會優於相對應的非泛用集合類別,而且也會優於衍生自非泛用基底集合類別的類別。
因此呢,如果您的應用程式過去曾經使用了某些非泛用集合類別,現在應該儘可能使用 .NET Framework 2.0 所新提供之相對應功能的泛用集合類別來加以改寫。請您參閱圖表 1,以便清楚瞭解 .NET Framework 2.0 新提供之泛用集合類別與原先之非泛用集合類別的功能對應關係。
泛用集合類別與非泛用集合類別的功能對應關係 | |
泛用集合類別 | 非泛用集合類別 |
List | ArrayList |
Dictionary | Hashtable |
Queue | Queue |
Stack | Stack |
SortedList | SortedList |
Collection | CollectionBase |
ReadOnlyCollection | ReadOnlyCollectionBase |
圖表 1
除了圖表 1 所列的各個泛用集合類別之外,.NET Framework 2.0 還新增了下列數個泛用集合類別,還這些泛用集合類別並沒有功能相對應的非泛用集合類別:
q 泛用集合類別 LinkedList 是一個通用的連結清單,它提供 O(1) 插入與移除操作。
q 泛用集合類別 SortedDictionary 是一個具備 O(log n) 插入與移除操作的排序字典,它很適合用來替換 SortedList。
q 泛用集合類別 KeyedCollection 可以說是清單與字典的混合體,它提供了一個方式來儲存擁有內嵌索引鍵的值。
在此還要提醒大家,泛用集合類別所擁有的某些功能性是非泛用集合類別所付之闕如的。舉例來說,以對應於非泛用集合類別 ArrayList 的泛用集合類別 List 而言,它就提供了好幾個能夠接收泛用委派的方法,例如 Predicate 委派允許您指定用來搜尋清單的方法;Action 委派代表要在清單中每一個項目上執行一個動作的方法;Converter 委派則能夠讓您定義型別之間的轉換。
另外呢,泛用集合類別 List 允許您指定您自己的泛用介面 IComparer 來排序與搜尋清單;泛用集合類別 SortedDictionary 與 SortedList 亦具備此能力,而且還允許在集合被建立時指定比較子;類似地,泛用集合類別 Dictionary 與 KeyedCollection 允許您指定您自己的相等比較子。
當您下次要使用到集合物件的時候,別忘了要把這些泛用集合類別納入考慮喔!
章立民研究室
參考資料: