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

構建可反轉排序的泛型字典類(一):從零開始的雛形設計

     編輯:關於C#

系列緣起:為何要重造輪子?

翻閱《C# Cookbook》第 4.8 節「反轉 Sorted List 裡的內容」,發現一個近 1300 行的 ReversibleSortedList 範例。代碼品質極高,值得深度剖析。雖然實務專案中直接使用 FCL 現成集合(SortedDictionary、SortedList)即可,但手寫核心集合類別能:

  • 透過閱讀優質代碼提升架構能力
  • 理解 FCL 內部運作機制,踏出造輪子的第一步
  • 若您是元件開發者,「您越麻煩,使用者越方便」

資料結構選型:陣列為王

需求:存儲鍵值對(TKey, TValue),類型不固定 → 泛型。
儲存容器選擇:陣列。理由:存取速度最快、類型安全、語法簡潔。唯一缺點——容量固定,需自行實作動態擴容。

初版雛形(0.1 版)

public class ReversibleSortedList<TKey, TValue>
{
    private TKey[] keys;
    private TValue[] values;

    public int Capacity => this.keys.Length;
}

容量初始化的演進思考

問題:實例化後直接讀 Capacity 會拋出 NullReferenceException

keys 未初始化,無法存取 Length。

方案比較

方案代碼優點缺點
宣告時初始化空陣列 private TKey[] keys = new TKey[0]; 簡單可行 一聲明即成垃圾,感覺不潔
預設給固定容量(如 4) private TKey[] keys = new TKey[4]; 避免頻繁擴容 浪費 4 個槽位空間,違背完美主義
靜態共享空陣列(採用) private static TKey[] emptyKeys; 全程序僅一份空陣列,零浪費、零重複分配 需在靜態建構子初始化

最終初始化模式

#region 成員變數
private TKey[] keys;
private TValue[] values;
private static TKey[] emptyKeys;
private static TValue[] emptyValues;
#endregion

#region 建構子
static ReversibleSortedList() // 靜態建構子(型別建構子)
{
    emptyKeys = new TKey[0];
    emptyValues = new TValue[0];
}

public ReversibleSortedList() // 實例建構子
{
    this.keys = emptyKeys;
    this.values = emptyValues;
}
#endregion

public int Capacity => this.keys.Length;

驗證測試

public class Test
{
    static void Main()
    {
        var rs = new ReversibleSortedList<int, string>();
        Console.WriteLine(rs.Capacity); // 輸出 0
    }
}

執行結果:0 —— 完美運作,無例外、無多餘分配。

架構心得

  1. 靜態建構子保證執行時機:CLR 保證在建立第一個實例或存取任何靜態成員前執行,且執行緒安全。
  2. 空陣列單例模式:Array.Empty<T>()(.NET Core 2.0+)內部即採用此模式,我們手寫版本等同於早期 FCL 的最佳實踐。
  3. 分離關注點:keys/values 平行陣列設計,後續排序、插入、刪除時需同步搬移兩個陣列,增加複雜度但極大提升記憶體局部性與快取命中率。

下一篇將引入 Array.BinarySearch 實現 O(log n) 插入點查找,並設計支援升/降序切換的比較器架構。

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