首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# ArrayList 遷移 List<T> 進階:缺失成員補償與效能考量

     編輯:關於C語言

前言

將 ArrayList 遷移至 List<T> 時,會發現部分成員無直接對應。本文詳細說明如何透過介面轉型、擴充方法、替代方案補足功能缺口,並分析預設容量差異對效能的影響。

成員對應與補償策略總覽

ArrayList 成員List<T> 對應補償方案
IsReadOnly無((IList)list).IsReadOnly
IsFixedSize無((IList)list).IsFixedSize(永遠回傳 false)
IsSynchronized無((IList)list).IsSynchronized(永遠回傳 false)
SyncRoot無((IList)list).SyncRoot(回傳 this)
Repeat 靜態方法無自訂泛型擴充方法
Clone無list.GetRange(0, list.Count)
Synchronized 靜態方法無lock(list) { ... } 或專用同步物件
FixedSize/ReadOnly 靜態方法無list.AsReadOnly() 僅支援唯讀

介面轉型取得缺失屬性

List<int> numbers = new List<int>();

// 透過 IList 介面取得非泛型集合相容屬性
Console.WriteLine(((IList)numbers).IsReadOnly);      // false
Console.WriteLine(((IList)numbers).IsFixedSize);     // false
Console.WriteLine(((IList)numbers).IsSynchronized);  // false
Console.WriteLine(((IList)numbers).SyncRoot);        // 回傳 numbers 本身

注意:IsFixedSize 與 IsSynchronized 永遠回傳 false,因泛型集合不支援固定大小與內建同步包裝。SyncRoot 回傳 this,建議直接用 lock(numbers)。

Repeat 靜態方法替代方案

public static void Repeat<T>(List<T> list, T obj, int count)
{
    if (count < 0)
        throw new ArgumentException("count 必須 >= 0");
    
    for (int i = 0; i < count; i++)
        list.Add(obj);
}

// 使用範例
var list = new List<string>();
Repeat(list, "Hello", 3);  // 加入 3 個 "Hello"

Clone 替代方案:GetRange 實現淺拷貝

List<int> oldList = new List<int> { 1, 2, 3, 4, 5 };
// 複製全部元素
List<int> newList = oldList.GetRange(0, oldList.Count);

// 驗證獨立性
newList[0] = 99;
Console.WriteLine(oldList[0]);  // 1(原始未變)
Console.WriteLine(newList[0]);  // 99

GetRange 執行淺拷貝,參考型別元素仍指向同一物件,行為接近 ArrayList.Clone()。

同步化機制變更:棄用 Synchronized,改用 lock

// 非泛型寫法(已淘汰)
var syncList = ArrayList.Synchronized(list);

// 泛型標準寫法
private readonly object _lock = new object();
lock (_lock) { list.Add(item); }

// 或直接鎖定列表本身(簡單場景)
lock (list) { list.Add(item); }

微軟移除內建同步包裝,因其提供錯誤的安全感(複合操作仍需外部鎖定)。顯式 lock 更清晰、可控。

效能關鍵:預設容量差異

集合類型預設初始容量擴容次數(加入 17 元素)
ArrayList161 次(16→32)
List<T>43 次(4→8→16→32)

建議:若預估元素數量,建構時指定容量 new List<T>(estimatedCount) 避免多次擴容重新分配記憶體。

List<T> 獨有強大功能(ArrayList 無對應)

  • ConvertAll<TOutput>(Converter<T, TOutput>) - 型別轉換投影
  • Find/Predicate<T>、FindAll、FindIndex、FindLast - 條件搜尋
  • ForEach(Action<T>) - 內建迴圈動作
  • Exists/TrueForAll - 量詞邏輯
  • TrimExcess() - 釋放未使用容量

總結

遷移 ArrayList 至 List<T> 不僅是型別安全提升,更獲得豐富的函數式操作方法。雖少數非泛型成員需透過 IList 介面或自訂方法補足,但整體 API 設計更現代、更強大。記住指定初始容量以發揮最佳效能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved