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
相关产品推荐
相关产品推荐

