2

.Netでは、IDictionary<K, V>定義.Keys.Valuesプロパティがあり、それぞれがではICollection<>なくIEnumerable<>、より自然にフィットするように見えます。

のインスタンスを呼び出す、.Addまたはインスタンスを呼び出すための合理的なユースケースはありますか?.Remove.Keys.ValuesIDictionary<K, V>

4

2 に答える 2

1

いいえ、おそらく合理的なユースケースはありません。これには、正当な理由はほとんどありません(おそらくゼロです)。

Dictionary<TKey, TValue>クラスはそのforを返し、「KeyCollectionディクショナリから派生したキーコレクションを変更することは許可されていません」.KeysとスローNotSupportedExceptionします。直接追加しようとするときはいつでも。私はそれがレガシーの理由で戻ってくると想像します、そしておそらく今は絶対に避けるべきです。ICollection

実際、ICollectionから返されたから.Keysがそれを含むものへの参照を持っていない限りIDictionary、私は何も有用なことが起こるのを見ることができません。の.Addは、この追加が何を意味するICollectionのかを含むことを伝えなければなりません。IDictionaryおそらく、あなたは次のようなことをすることができる何らかの形を実装したかったでしょうSet

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

キーまたは値のコレクションを呼び出すAdd、または使用するための合理的なユースケースは考えられません。Remove結果の辞書はどのようになると思いますか?

フレームワークに組み込まれているのすべての実装は、実行しようとすると、、または同様のものIDictionary<K,V>をスローすると確信しています。NotSupportedException(そして、おそらくあなた自身の実装のどれでも同じことをするべきです。)

于 2013-03-27T00:31:18.370 に答える