非泛型 Queue、Stack 使用 object 儲存元素,導致值型別頻繁裝箱/拆箱。本文提供完整遷移範例,展示改用 Queue<T>、Stack<T> 的代碼變更與效能收益。
public static void UseNonGenericQueue()
{
Queue numericQueue = new Queue();
numericQueue.Enqueue(1); // 裝箱 int → object
numericQueue.Enqueue(2); // 裝箱
numericQueue.Enqueue(3); // 裝箱
Console.WriteLine(numericQueue.Dequeue()); // 拆箱 object → int
Console.WriteLine(numericQueue.Dequeue()); // 拆箱
Console.WriteLine(numericQueue.Dequeue().ToString()); // 拆箱
}
public static void UseGenericQueue()
{
Queue<int> numericQueue = new Queue<int>();
numericQueue.Enqueue(1); // 直接存入 int[],無裝箱
numericQueue.Enqueue(2);
numericQueue.Enqueue(3);
Console.WriteLine(numericQueue.Dequeue()); // 直接讀取 int,無拆箱
Console.WriteLine(numericQueue.Dequeue());
Console.WriteLine(numericQueue.Dequeue());
}
public static void UseNonGenericStack()
{
Stack numericStack = new Stack();
numericStack.Push(1); // 裝箱
numericStack.Push(2); // 裝箱
numericStack.Push(3); // 裝箱
Console.WriteLine(numericStack.Pop().ToString()); // 拆箱
Console.WriteLine(numericStack.Pop().ToString()); // 拆箱
Console.WriteLine(numericStack.Pop().ToString()); // 拆箱
}
public static void UseGenericStack()
{
Stack<int> numericStack = new Stack<int>();
numericStack.Push(1); // 直接存入 int[]
numericStack.Push(2);
numericStack.Push(3);
Console.WriteLine(numericStack.Pop().ToString()); // 直接讀取 int
Console.WriteLine(numericStack.Pop().ToString());
Console.WriteLine(numericStack.Pop().ToString());
}
| 項目 | 非泛型 | 泛型 | 效益 |
|---|---|---|---|
| 命名空間 | System.Collections | System.Collections.Generic | — |
| 宣告語法 | new Queue() | new Queue<int>() | 編譯期型別檢查 |
| Enqueue/Push 參數 | object | T (int) | 無裝箱 |
| Dequeue/Pop 回傳 | object | T (int) | 無拆箱、無轉型 |
| foreach 迭代變數 | object 需轉型 | T 直接使用 | 程式碼簡潔 |
int、double、DateTime、Guid 等值型別struct(座標點、向量、金融數據)Clone(),改用 new Queue<T>(source)lock 陳述式Queue<object>(但失去型別安全優勢)Queue<T>、Stack<T> 是非泛型版本的直接升級替代品:語法幾乎相同、編譯器提供型別安全、執行期消除裝箱/拆箱。只要專案目標框架 ≥ .NET 2.0,無理由繼續使用非泛型版本處理值型別。