常用的 Collection 跟 Generic

011 | C# CodeHelper
From: 011netservice@gmail.com
Date: 2022-04-24
Subject: 常用的 Collection 跟 Generic

摘要:
  1. Array雖然不是Collection, 但是因為性質相近, 並且也實作了許多Collection介面可使用, 因此也列入比較.
  2. 如有相同的功能, 則應優先使用基本型別的 collection, 其次可選用泛型Generic版本的collection, 最後才考慮使用Object型別的Collection. 盡量避開boxing/unboxing的執行過程, 以提高效能.
  3. Object型別的Collection可適用於存放異質型別(heterogeneous)的集合.
  4. Generic泛型版本的Collection, 執行效能高, 但是若要做為介面傳遞參數時, 較為不方便, 必須注意呼叫端與接收端, 都使用相同型別宣告才能傳遞. 此外, 若指定<T>, <TKey>為自訂型別時, 則必須實作IComparable介面, 否則無法提供Key查詢或Sort功能. (.net的本身的基本型別如int, long, string, DateTime...等已實作IComparable介面).
  5. 基本型別的Collection, 執行效能高, 使用也很方便. 但是適用範圍較小.
  6. 若需要自訂Collection型別,  則可繼承自 Collection<T> 或 KeyedCollection<TKey, TItem>, 實作自行定義的Collection, 可以兼顧執行效能及使用便利性.
  7. 記憶體中資料處理, 除了Array, Collection之外, 還有DataTable可以使用. DataTable同樣可以新增、刪除、修改或查詢, 以及排序記憶體中的欄位或紀錄資料, 使用上較為直覺.
  8. 欄位(優先) = 優先選用順序. 以使用方便為優先考慮順序, 執行效能排其次.
範例程式可自C# CodeHelper取得.

單一元素組合:

No. Collection Index Key 元素
型別
Sorted Generic 元素個數 優先 Description
1 Array Y N 宣告時指定 N N 固定. 1.2 存放固定個數的元素, 宣告時需指定元素型別.
  1. 內建於語言的基本元素. 雖然並非歸類為Collections. 但是因為繼承了 IList 介面, 因此仍有Collection的特性.
  2. 建立陣列時, 需指定固定的元素個數.
  3. 預設以0為lower bound. 建立Array時可指定不同的lower bound.
  4. 可建立為多階陣列, 最多32階.
  5. 同時實作了以下介面, 因此可擁有最多使用方式的屬性或方法:
    • System.Collections.Generic.IList
    • System.Collections.Generic.ICollection<T>
    • System.Collections.Generic.IEnumerable<T>
2 StringCollection Y N string N N 變動 1.1 存放string型別的元素清單.
  1. 可以index存取.
  2. 不維持排序.
  3. 元素可重複.
3 ArrayList Y N Object N N 變動 2 存放Object型別的元素清單.
  1. 效能較差, 因存取值時, 須進行型別轉換處理(boxing/unboxing).
  2. 適用於存放異質型別(heterogeneous)的集合.
  3. 可以index存取元素.
  4. 不維持排序.
  5. 元素可為null.
  6. 元素可重複.
4 List<T> Y N 宣告時指定 N Y 變動 3.3 存放指定型別的元素清單.
  1. 若需存放異質型別元素, 則可宣告T為Object型別. (這樣等於ArrayList)
  2. 可以index存取元素.
  3. 不維持排序.
  4. 元素可重複.
5 HashSet<T> N Y 宣告時指定 N Y 變動 3.2 等於只有TKey的Dictionary<TKey, TValue>.
TKey經過雜湊函數處理後才存取, 以提高搜尋效能.
  1. 可以Key存取元素.
  2. 不維持排序.
  3. Key不可重複.
6 SortedSet<T> N Y 宣告時指定 Y Y 變動 3.1 等於只有TKey的SortedDictionary<TKey, TValue>.
.Net 4.0以上才支援.
  1. 可以Key存取元素.
  2. 維持排序.
  3. Key不可重複.

Key/Value 組合:

摘要:
Key/Value的組合, 都可使用Key查詢元素.
從使用介面的角度來看, 相同的功能卻有重複的元件可以使用, 原因是元件內部實作方式不同. 例如: 命名為Dictionary系列的元件, 內部是以Tree的方式實作存取元素; SortedList系列的元件, 內部則是以兩個class維護Index跟Key. 兩者相對比較, Tree需要多花費運算效能, 後者則需要多一點儲存記憶體. 當小量的運算或資料時, 差異不大, 並不需要特別選擇. 只有碰到大量運算或資料時, 才需要評估選擇較適合的元件.
No. Collection 元素型別 Index Key Value Sorted Generic 優先 Description
1 StringDictionary DictionaryEntry N string string N N 1.1 以hash table存放(key與value均為string型別)的元素清單.
2 Hashtable DictionaryEntry
N Object Object N N 2.2 存放(Key和Value均為Object型別)的DictionaryEntry元素清單. Key值會經過運算雜湊函數處理後存取, 以提高搜尋效能.
3 Dictionary<TKey, TValue> KeyValuePair N 依宣告 依宣告 N Y 3.3 存放指定型別的KeyValuePair元素清單.
內部以Tree方式實作.
4 SortedDictionary<TKey, TValue> KeyValuePair N 依宣告 依宣告 Y Y 3.2 存放(Key和Value為指定型別)的KeyValuePair元素清單, 並維持排序. 僅能以Key存取元素.
內部以Tree方式實作.
5 OrderedDictionary DictionaryEntry Y Object Object N N 2.3 存放(Key與Value均為Object型別)的DictionaryEnrty元素清單. , 並維持排序. 可同時使用Index或Key存取元素. Index值會隨著Key值變動.
內部以Tree方式實作.
6 NameValueCollection Name=string
Value=string
Y string
可重複
string N N 1.2 存放(Name與Value均為string型別)的元素清單. 可同時以Index或Name值存取元素. 同一個Name可以重複, 也可以存放多組的字串. 常用於headers, query string and form data.
7 SortedList DictionaryEntry
Y
Object Object Y N 2.1 存放(Key和Value均為Object型別)的DictionaryEntry元素清單, 並維持排序. 可同時使用Index或Key存取元素. Index值會隨著Key值變動.
內部以兩個class維護index跟Key. 須使用較多的記憶體.
8 SortedList<TKey, TValue> KeyValuePair Y 依宣告 依宣告 Y Y 3.1 存放(指定型別的Key和Value)的KeyValuePair元素清單, 並維持排序. 可同時使用Index或Key存取元素. Index值會隨著Key值變動.
內部以兩個class維護index跟Key. 須使用較多的記憶體.

Inheritance Hierarchy

System.Array:

No. Name Index Key Sorted Description
1 Array
陣列
Y N N 存放(宣告時指定型別及元素數量)陣列.
  1. 內建於語言的陣列, 是最基本且用途最廣的物件. 雖然並非歸屬為System.Collections. 但是因為繼承自ILis介面, 因此仍有Collection的特性.
  2. 建立陣列時, 需指定固定的元素個數.
  3. 預設以0為lower bound. 建立Array時可指定不同的lower bound.
  4. 可建立為多階陣列, 最多32階.
  5. 同時實作了以下介面, 因此可以使用最多變化的屬性或方法:
    • System.Collections.Generic.IList
    • System.Collections.Generic.ICollection<T>
    • System.Collections.Generic.IEnumerable<T>

System.Collections:

No. Collections Index Key Sorted Description
1 ArrayList Y N N 存放Object型別的元素清單.
效能較差, 不建議使用!
若元素型別不相同(heterogeneous),則優先改用List<Object>, 否則改用List<T>.
(註: 型別相同為同質型別(homogeneous), 否則為異質型別(heterogeneous).
2 CollectionBase Y N N abstract base物件可用於設計自訂的Collection物件.
3 DictionaryBase N Y N abstract base物件可用於設計自訂的Dictionary物件.
4 Hashtable N Y N 存放(Key和Value均為Object型別)的DictionaryEntry元素清單. Key值會經過運算雜湊函數處理後存取, 以提高搜尋效能.
  1. 以雜湊表存放計算後的排序結果, 需多使用記憶體空間.
  2. 元素為DictionaryEntry物件的key/value pair. Key不可為null, Value可以為null.
  3. 預設以0為lower bound. 建立Array時可指定不同的lower bound.
  4. 可建立為多階陣列, 最多32階.
  5. 建立陣列時, 需指定固定的元素個數.
  6. 同時實作了以下介面, 因此可以使用相同的屬性或方法:
    • System.Collections.Generic.IList
    • System.Collections.Generic.ICollection<T>
    • System.Collections.Generic.IEnumerable<T>
5 Queue     佇列. FIFO.
6 SortedList Y Y Y 存放(Key和Value均為Object型別)的DictionaryEntry元素清單, 並維持排序. 可同時使用Index或Key存取元素. Index值會隨著Key值變動.
7 Stack       堆疊. FILO.

System.Collections.Generic:

No. Name Index Key Sorted Description
1 Dictionary<TKey, TValue> N Y N 存放指定型別的KeyValuePair元素清單.
2 HashSet<T> N Y N 存放指定型別的Key元素清單.
等於只有TKey的Dictionary, 並且TKey經過雜湊函數處理後才存取, 以提高搜尋效能.
3 KeyValuePair<TKey, TValue> Structure       以Structure型別存放Dictionary<TKey, TValue>.Enumerator.Current屬性.
使用於Dictionary foreach敘述時, 讀取單一元素.
4 LinkedList<T>       以雙向連結存放元素清單.
5 List<T> Y N N 存放指定型別的元素清單.
6 Queue<T>       以佇列存放指定型別的元素清單.
7 SortedDictionary<TKey, TValue> N Y Y 存放(Key和Value為指定型別)的KeyValuePair元素清單, 並維持排序. 僅能以Key存取元素.
8 SortedList<TKey, TValue> Y Y Y 存放(指定型別的Key和Value)的KeyValuePair元素清單, 並維持排序. 可同時使用Index或Key存取元素. Index值會隨著Key值變動.
9 SortedSet<T> N Y Y 等於只有TKey的SortedDictionary<TKey, TValue>.
.Net 4.0以上才有支援.
10 Stack<T>       以堆疊存放指定型別的元素清單.

System.Collections.ObjectModel:

No. Name Index Key Sorted Description
1 Collection<T> Y N N abstract物件可自訂Collection存放指定型別的元素清單.
必須繼承使用.
2 KeyedCollection<TKey, TItem> Y Y N abstract物件可自訂KeyCollection存放指定型別的(TKey與TItem)元素清單. 可同時以Index或Key值存取元素.
必須繼承使用.
適用例: TKey=訂單編號, TItem=訂單屬性.

System.Collections.Specialized:

No. Name Index Key Sorted Description
1 NameObjectCollectionBase Y Y N abstract物件, 可用來繼承存放(Key為string, Value為Object)型別的元素清單. 可同時以Index或Key值存取元素.
2 NameValueCollection Y Y N 存放(Key與Value均為string型別)的元素清單. 可同時以Index或Key值存取元素. 同一個Key可以存放多組的字串. 適用於headers, query string and form data.
3 OrderedDictionary Y Y N 存放(Key與Value均為Object型別)的DictionaryEnrty元素清單. 可同時以Index或Key值存取元素.
4 StringCollection Y N N 存放(string型別)的元素清單. 可以index存取元素.
5 StringDictionary N Y N 以hash table存放(key與value均為string型別)的元素清單. 可以key存取元素.
6 StringEnumarator       支援StringCollection的foreach enumerator.




Reference:
System.Array
System.Collections
System.Collections.Generic
System.Collections.ObjectModel
System.Collections.Specialized


Log:
Date Author Description
2017-01-30 Honda copy from luckstat document.
2017-03-17 Honda 更新範例程式.
2017-04-22 Honda 補充說明.
011 | C# CodeHelper