.NET - dictionary.Keys.Add? [英] .net - dictionary.Keys.Add?

查看:295
本文介绍了.NET - dictionary.Keys.Add?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在.NET中,的IDictionary< K,V> 定义。键。值属性,每一个都是一个的ICollection<> ,而不是的IEnumerable<> ,这似乎是这将是一个更自然的适合我。

In .Net, IDictionary<K, V> defines .Keys and .Values properties, each of which is an ICollection<> rather than IEnumerable<>, which seems like it would be a more natural fit to me.

有没有合理的使用情况下调用。新增卸下摆臂。键的一个实例 .Values​​ 的IDictionary&LT; K,V&GT;

Is there any reasonable use case to call .Add or .Remove on .Keys or .Values of an instance of an IDictionary<K, V>?

推荐答案

没有,大概没有合理的使用情况。有极少数(可能是零)正当理由的。

No, probably no reasonable use case. There are very few (probably zero) legitimate reasons for this at all.

词典&LT; TKEY的,TValue&GT; 类返回 KeyCollection 。键这又抛出 NotSupportedException异常变异从字典中是不允许的派生的密钥集合。只要努力直接添加到它。我想,它返回一个的ICollection 遗留原因,而且也应该不惜一切代价避免了。

The Dictionary<TKey, TValue> class returns a KeyCollection for its .Keys which in turn throws NotSupportedException with "Mutating a key collection derived from a dictionary is not allowed." whenever trying to add directly to it. I imagine that it returns an ICollection for legacy reasons and probably should be avoided at all costs now.

事实上,除非从的ICollection 返回。键有一个参照其含有 IDictionary的,我看不出任何有用的东西发生。该。新增的ICollection 将不得不告诉含的IDictionary 这是什么意思插件。也许你想实现某种形式的设置你可以做这样的事情:

In fact unless the ICollection returned from .Keys had a reference to its containing IDictionary, I can't see anything useful happen. The .Add of the ICollection would have to tell the containing IDictionary what this add meant. Perhaps you wanted to implement some form of a Set you could do something like this:

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(); }
}

当然,还有一个更好的方法来实现这种或类似您的特定需求。这样做的唯一好处是让。新增在返回 StringCollection 。我想用我的 StringSet 使用父 StringSet 类反正迫人。但是,它有可能会有人想上面覆盖的行为。

Surely there is a better way to implement this or similar for your specific needs. The only benefit this has is allowing .Add on the returned Keys StringCollection. I would want to force people using my StringSet to use the parent StringSet class anyway. But, it is possible that someone would want the above overridden behavior.

这个调用它:

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"]);

这篇关于.NET - dictionary.Keys.Add?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆