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

構建可反轉排序的泛型字典 (4/9):IDictionary 介面詳解與簡易實現範例

     編輯:關於C#

.NET 集合介面體系

  • IEnumerable:統一遍歷協定,支援 `foreach`。
  • ICollection:所有集合基介面,提供 `Count`、`CopyTo`、`IsSynchronized`、`SyncRoot`。
  • IDictionary:鍵值對集合介面,繼承 `ICollection`、`IEnumerable`,定義 `Keys`、`Values`、`Item`(索引器)、`Add`/`Remove`/`Contains`/`Clear`、`GetEnumerator()` 返回 `IDictionaryEnumerator`。

IDictionary 核心成員表

| 成員 | 類型 | 說明 | |------|------|------| | `Item[object key]` | 索引器 | 獲取/設置指定鍵的值 | | `Keys` | `ICollection` | 所有鍵的集合視圖 | | `Values` | `ICollection` | 所有值的集合視圖 | | `Add(key, value)` | 方法 | 添加鍵值對 | | `Remove(key)` | 方法 | 移除指定鍵 | | `Contains(key)` | 方法 | 是否包含鍵 | | `Clear()` | 方法 | 清空集合 | | `GetEnumerator()` | 方法 | 返回 `IDictionaryEnumerator` | | `IsFixedSize`/`IsReadOnly` | 屬性 | 集合特性 |

簡易實現範例:SimpleDictionary

以陣列存儲 `DictionaryEntry`,展示介面實現骨架:


public class SimpleDictionary : IDictionary
{
    private DictionaryEntry[] _items;
    private int _count;

    public SimpleDictionary(int capacity) => _items = new DictionaryEntry[capacity];

    #region IDictionary
    public bool IsReadOnly => false;
    public bool IsFixedSize => false;

    public object this[object key]
    {
        get
        {
            int idx = IndexOfKey(key);
            return idx >= 0 ? _items[idx].Value : null;
        }
        set
        {
            int idx = IndexOfKey(key);
            if (idx >= 0) _items[idx].Value = value;
            else Add(key, value);
        }
    }

    public ICollection Keys
    {
        get
        {
            var keys = new object[_count];
            for (int i = 0; i < _count; i++) keys[i] = _items[i].Key;
            return keys;
        }
    }

    public ICollection Values
    {
        get
        {
            var vals = new object[_count];
            for (int i = 0; i < _count; i++) vals[i] = _items[i].Value;
            return vals;
        }
    }

    public void Add(object key, object value)
        => _items[_count++] = new DictionaryEntry(key, value);

    public void Clear() => _count = 0;

    public bool Contains(object key) => IndexOfKey(key) >= 0;

    public IDictionaryEnumerator GetEnumerator()
        => new SimpleEnumerator(this);

    public void Remove(object key)
    {
        int idx = IndexOfKey(key);
        if (idx >= 0)
        {
            Array.Copy(_items, idx + 1, _items, idx, _count - idx - 1);
            _count--;
        }
    }

    private int IndexOfKey(object key)
    {
        for (int i = 0; i < _count; i++)
            if (_items[i].Key.Equals(key)) return i;
        return -1;
    }
    #endregion

    #region ICollection
    public int Count => _count;
    public bool IsSynchronized => false;
    public object SyncRoot => this;
    public void CopyTo(Array array, int index) => throw new NotImplementedException();
    #endregion

    #region IEnumerable
    IEnumerator IEnumerable.GetEnumerator() => ((IDictionary)this).GetEnumerator();
    #endregion

    // 內部枚舉器:複製數據避免並發問題(教學簡化)
    private class SimpleEnumerator : IDictionaryEnumerator
    {
        private readonly DictionaryEntry[] _items;
        private int _index = -1;

        public SimpleEnumerator(SimpleDictionary dict)
        {
            _items = new DictionaryEntry[dict.Count];
            Array.Copy(dict._items, _items, dict.Count);
        }

        public object Current => _items[_index];
        public DictionaryEntry Entry => (DictionaryEntry)Current;
        public object Key => _items[_index].Key;
        public object Value => _items[_index].Value;
        public bool MoveNext() => ++_index < _items.Length;
        public void Reset() => _index = -1;
    }
}

關鍵設計點解析

  1. 索引器即 Item 屬性:`this[object key]` 是 C# 索引器語法糖,編譯為 `get_Item`/`set_Item`。
  2. Keys/Values 返回陣列:陣列實現 `ICollection`,簡單但每次訪問都會分配新陣列(效能隱患)。生產級實現應返回視圖(見第 6 篇)。
  3. 枚舉器複製數據:`SimpleEnumerator` 構造時 `Array.Copy` 所有元素,避免枚舉期間集合修改導致錯誤,但引入 O(n) 空間/時間開銷。高效做法見第 5 篇版本號機制。
  4. IEnumerable.GetEnumerator 顯式實現:強制轉型為 `IDictionary` 調用其 `GetEnumerator()`,複用邏輯。

測試代碼


static void Main()
{
    IDictionary dict = new SimpleDictionary(3);
    dict.Add("Jeff", 40);
    dict.Add("Kristin", 34);
    dict.Add("Aidan", 1);

    Console.WriteLine($"Count: {dict.Count}");
    Console.WriteLine($"Contains 'Jeff': {dict.Contains("Jeff")}");
    Console.WriteLine($"Jeff's age: {dict["Jeff"]}");

    foreach (DictionaryEntry de in dict)
        Console.WriteLine($"{de.Key} is {de.Value} years old.");

    dict.Remove("Jeff");
    dict.Remove("Max"); // 不拋異常

    foreach (string key in dict.Keys) Console.WriteLine(key);
    foreach (int age in dict.Values) Console.WriteLine(age);
}

本章小結

理解 `IDictionary` 介面契約、索引器語法、枚舉器模式、顯式介面實現,是構建高性能泛型字典的基石。下一篇將引入泛型、二分查找、自動擴容、自定義比較器,邁向生產級實現。

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