You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中HashDictionary实现遇到多类问题求助

问题解决方向提示

1. 泛型GetEnumerator()实现

首先你的HashDictionaryEnumerator需要实现泛型接口IEnumerator<KeyValuePair<TKey, TValue>>,而非仅实现非泛型的IEnumerator。这样泛型版本的GetEnumerator可直接返回该枚举器实例,非泛型版本则可通过显式实现调用泛型版本。

修改枚举器定义:

public class HashDictionaryEnumerator : IEnumerator<KeyValuePair<TKey, TValue>>
{
    private readonly LinkedList<KeyValuePair<TKey, TValue>>[] _buckets;
    private LinkedListNode<KeyValuePair<TKey, TValue>> _currentNode;
    private int _currentIndex;

    // 构造函数
    public HashDictionaryEnumerator(LinkedList<KeyValuePair<TKey, TValue>>[] buckets)
    {
        _buckets = buckets;
        _currentIndex = -1;
        _currentNode = null;
    }

    // 泛型Current属性
    public KeyValuePair<TKey, TValue> Current => _currentNode.Value;

    // 非泛型Current显式实现
    object IEnumerator.Current => Current;

    // MoveNext、Reset、Dispose等方法实现见后续修复部分

    public void Reset()
    {
        _currentIndex = -1;
        _currentNode = null;
    }

    public void Dispose()
    {
        // 空实现即可,无托管资源需释放
    }
}

然后在HashDictionary中实现泛型与非泛型枚举器:

public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
    return new HashDictionaryEnumerator(Buckets);
}

IEnumerator IEnumerable.GetEnumerator()
{
    return GetEnumerator();
}

2. Contains(KeyValuePair<TKey, TValue> item)方法实现问题

直接用==比较KeyValuePair会因类型特性(引用类型比引用、自定义值类型未重载==)失效,需用EqualityComparer<T>做标准化比较:

public bool Contains(KeyValuePair<TKey, TValue> item)
{
    int index = GetIndex(item.Key);
    var bucket = Buckets[index];
    if (bucket == null)
        return false;

    var keyComparer = EqualityComparer<TKey>.Default;
    var valueComparer = EqualityComparer<TValue>.Default;

    foreach (var pair in bucket)
    {
        if (keyComparer.Equals(pair.Key, item.Key) && valueComparer.Equals(pair.Value, item.Value))
        {
            return true;
        }
    }
    return false;
}

3. Add方法的问题修复

当前Add方法会覆盖整个桶(每次添加都新建LinkedList),导致同桶内原有数据丢失。正确逻辑应为:

  • 先检查桶是否存在,不存在才创建
  • 添加前检查键是否已存在,避免重复
public void Add(TKey key, TValue value)
{
    int index = GetIndex(key);
    var bucket = Buckets[index];
    
    // 检查键是否已存在
    if (bucket != null)
    {
        var keyComparer = EqualityComparer<TKey>.Default;
        foreach (var pair in bucket)
        {
            if (keyComparer.Equals(pair.Key, key))
            {
                throw new ArgumentException("Key already exists in the dictionary.");
            }
        }
    }
    else
    {
        bucket = new LinkedList<KeyValuePair<TKey, TValue>>();
        Buckets[index] = bucket;
    }
    
    bucket.AddLast(new KeyValuePair<TKey, TValue>(key, value));
}

4. 枚举器逻辑修复

原枚举器存在空引用风险、索引初始化错误、遍历逻辑漏洞,修复后代码:

public bool MoveNext()
{
    // 当前节点有下一个元素,直接移动
    if (_currentNode != null && _currentNode.Next != null)
    {
        _currentNode = _currentNode.Next;
        return true;
    }

    // 切换到下一个有效桶
    return MoveToNextValidBucket();
}

private bool MoveToNextValidBucket()
{
    _currentIndex++;
    while (_currentIndex < _buckets.Length)
    {
        var bucket = _buckets[_currentIndex];
        if (bucket != null && bucket.First != null)
        {
            _currentNode = bucket.First;
            return true;
        }
        _currentIndex++;
    }
    _currentNode = null;
    return false;
}

内容的提问来源于stack exchange,提问作者user21425036

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 21:13:16