多值字典枚举

时间:2019-03-31 20:22:55

标签: c# .net

我试图用C#自己实现MultiValueDictionary。我在实现IEnumerable时遇到问题。

我使用IDictionary<K, HashSet<V>>作为内部结构。 我将枚举器从字典和哈希集分配给字段,然后尝试遍历它们。问题是:_keysEnum.Current.Value始终为null,每次我得到空集合时。内部字典在哈希集中包含正确的值。

public class MultiValueDictionaryEnumerator<K, V> : IEnumerator<KeyValuePair<K, V>>
{
    private IDictionary<K, HashSet<V>> _dict;
    private IEnumerator<KeyValuePair<K, HashSet<V>>> _keysEnum;
    private HashSet<V>.Enumerator _setEnum;
    private bool _setEnumInit;

    public MultiValueDictionaryEnumerator(IDictionary<K, HashSet<V>> dict)
    {
        _dict = dict;
        Reset();
    }
    public KeyValuePair<K, V> Current => KeyValuePair.Create(_keysEnum.Current.Key, _setEnum.Current);

    object IEnumerator.Current => Current;

    public void Dispose()
    {
    }

    public bool MoveNext()
    {
        var result = false;
        if (_setEnumInit)
        {
            result = _setEnum.MoveNext();
            if (!result)
            {
                result = _keysEnum.MoveNext();
                if (result)
                {
                    _setEnum = _keysEnum.Current.Value.GetEnumerator();
                }
            }
        }

        return result;
    }

    public void Reset()
    {
        _keysEnum = _dict.GetEnumerator();
        if (_keysEnum.Current.Value != null)
        {
            _setEnum = _keysEnum.Current.Value.GetEnumerator();
            _setEnumInit = true;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

这是IEnumerable的实现。明确地实现IEnumerator太麻烦了。

public class MultiValueDictionary<K, V> : IEnumerable<KeyValuePair<K, V>>
{
    private IDictionary<K, HashSet<V>> _dict;

    public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
    {
        foreach (var entry in _dict)
        {
            var hashSet = entry.Value;
            foreach (var item in hashSet)
            {
                yield return new KeyValuePair<K, V>(entry.Key, item);
            }
        }
    }

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