ArrayList 內部使用 object[] 儲存元素,導致值型別每次存取皆產生裝箱/拆箱。本文透過對比範例,展示改用 List<T> 如何徹底消除此開銷,並說明遷移的簡單步驟。
public static void UseNonGenericArrayList()
{
ArrayList numbers = new ArrayList();
numbers.Add(1); // 裝箱:int → object
numbers.Add(2); // 裝箱:int → object
// 迴圈拆箱:object → int
foreach (int i in numbers)
{
Console.WriteLine(i); // 每次迭代產生拆箱
}
numbers.Clear();
}
IL 代碼證據:
// Add(1) 產生
IL_000A: ldc.i4.1
IL_000B: box [mscorlib]System.Int32 // 裝箱指令
IL_0010: callvirt ... ArrayList::Add(object)
// foreach 拆箱
IL_0025: unbox.any [mscorlib]System.Int32 // 拆箱指令
public static void UseGenericList()
{
List<int> numbers = new List<int>();
numbers.Add(1); // 直接寫入 int[] 陣列,無裝箱
numbers.Add(2); // 直接寫入 int[] 陣列,無裝箱
// 直接讀取 int,無拆箱
foreach (int i in numbers)
{
Console.WriteLine(i);
}
numbers.Clear();
}
關鍵差異:List<int> 內部陣列為 int[],元素直接儲存整數值,無型別轉換指令。
| 操作 | ArrayList | List<int> | 差異 |
|---|---|---|---|
| 加入 100 萬整數 | ~1,000 萬次裝箱分配 | 零分配 | 記憶體/GC 壓力大幅降低 |
| 遍歷 100 萬整數 | 100 萬次拆箱 | 零拆箱 | CPU 週期顯著節省 |
| 記憶體佔用 | 物件標頭 + 陣列參考 | 緊湊 int[] 陣列 | 約節省 50% 記憶體 |
using System.Collections.Generic; 取代 System.CollectionsList<int> list = new List<int>(); 取代 ArrayList list = new ArrayList();(int)、(string) 等強制轉型Point、DateTime、自訂 struct)ArrayList 儲存值型別的現有代碼將 ArrayList 替換為 List<T> 是 .NET 應用程式最具投資報酬率的效能優化之一:代碼變更最小、編譯器保證正確性、效能提升顯著。只要集合元素為值型別,無理由繼續使用 ArrayList。