2

在 .Net 中,IDictionary<K, V>定义.Keys.Values属性中的每一个都是一个ICollection<>而不是IEnumerable<>,这似乎更适合我。

是否有任何合理的用例可以调用.Add.Remove的实例.Keys.ValuesIDictionary<K, V>

4

2 回答 2

1

不,可能没有合理的用例。这根本没有什么(可能是零)合理的理由。

该类为其Dictionary<TKey, TValue>返回一个,然后抛出“不允许更改从字典派生的键集合”。每当尝试直接添加到它时。我想它会因为遗留原因而返回,现在可能应该不惜一切代价避免。KeyCollection.KeysNotSupportedExceptionICollection

事实上,除非ICollection返回的 from.Keys引用了它的 contains IDictionary,否则我看不到任何有用的事情发生。的.AddICollection不得不告诉包含IDictionary此添加的含义。也许您想实现某种形式的 aSet您可以执行以下操作:

public class StringSet : IDictionary<string, int> {
    private readonly Dictionary<string, int> _InternalDictionary = new Dictionary<string, int>();
    public int this[string key] {
        get { return _InternalDictionary[key]; }
        set { _InternalDictionary[key] = value; }
    }

    private StringCollection _Keys;
    public ICollection<string> Keys {
        get {
            if(_Keys == null) _Keys = new StringCollection(this);
            return _Keys;
        }
    }
    ICollection<string> IDictionary<string, int>.Keys {
        get {
            if(_Keys == null) _Keys = new StringCollection(this);
            return _Keys;
        }
    }

    public ICollection<int> Values { get { throw new NotImplementedException();} }

    public void Add(string key, int value) { _InternalDictionary.Add(key, value); }
    public bool ContainsKey(string key) { return _InternalDictionary.ContainsKey(key); }
    public bool Remove(string key) { return _InternalDictionary.Remove(key); }

    public bool TryGetValue(string key, out int value) { return _InternalDictionary.TryGetValue(key, out value); }
    public void Clear() { throw new NotImplementedException(); }

    public void Add(KeyValuePair<string, int> item) { throw new NotImplementedException(); }
    public bool Contains(KeyValuePair<string, int> item) { throw new NotImplementedException(); }
    public void CopyTo(KeyValuePair<string, int>[] array, int arrayIndex) { throw new NotImplementedException(); }
    public bool Remove(KeyValuePair<string, int> item) { throw new NotImplementedException(); }

    public int Count { get { return _InternalDictionary.Count; } }
    public bool IsReadOnly { get { return false; } }

    public IEnumerator<KeyValuePair<string, int>> GetEnumerator() { throw new NotImplementedException(); }
    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}

public class StringCollection : ICollection<string> {
    private readonly StringSet _ContainingSet;
    public StringCollection(StringSet set) {
        _ContainingSet = set;
    }

    public void Add(string item) {
        if(_ContainingSet.ContainsKey(item)) _ContainingSet[item]++;
        else _ContainingSet[item] = 1;
    }

    public bool Contains(string item) { return _ContainingSet.ContainsKey(item); }
    public bool Remove(string item) { throw new NotImplementedException(); }

    public void Clear() { throw new NotImplementedException(); }
    public void CopyTo(string[] array, int arrayIndex) { throw new NotImplementedException(); }

    public int Count { get { return _ContainingSet.Count; } }
    public bool IsReadOnly { get { return false; } }

    public IEnumerator<string> GetEnumerator() { throw new NotImplementedException(); }
    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}

当然,根据您的特定需求,有更好的方法来实现这个或类似的。唯一的好处是允许.Add返回Keys StringCollection。无论如何,我想强制使用我StringSet的人使用父StringSet类。但是,有人可能想要上述被覆盖的行为。

用这个调用它:

var set = new StringSet();
var keys = set.Keys;
keys.Add("hello");
keys.Add("hello");
keys.Add("world");
Debug.Print("hello: {0}, world: {1}", set["hello"], set["world"]);
于 2013-03-27T01:43:07.810 回答
0

我想不出任何合理的调用AddRemove键或值集合的用例。您希望生成的字典是什么样的?

我很确定,如果您尝试这样做,所有框架的内置实现IDictionary<K,V>都会抛出一个或类似的。NotSupportedException(你也应该在你自己的任何实现中做同样的事情。)

于 2013-03-27T00:31:18.370 回答