.Netでは、IDictionary<K, V>
定義.Keys
と.Values
プロパティがあり、それぞれがではICollection<>
なくIEnumerable<>
、より自然にフィットするように見えます。
のインスタンスを呼び出す、.Add
またはインスタンスを呼び出すための合理的なユースケースはありますか?.Remove
.Keys
.Values
IDictionary<K, V>
.Netでは、IDictionary<K, V>
定義.Keys
と.Values
プロパティがあり、それぞれがではICollection<>
なくIEnumerable<>
、より自然にフィットするように見えます。
のインスタンスを呼び出す、.Add
またはインスタンスを呼び出すための合理的なユースケースはありますか?.Remove
.Keys
.Values
IDictionary<K, V>
いいえ、おそらく合理的なユースケースはありません。これには、正当な理由はほとんどありません(おそらくゼロです)。
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"]);
キーまたは値のコレクションを呼び出すAdd
、または使用するための合理的なユースケースは考えられません。Remove
結果の辞書はどのようになると思いますか?
フレームワークに組み込まれているのすべての実装は、実行しようとすると、、または同様のものIDictionary<K,V>
をスローすると確信しています。NotSupportedException
(そして、おそらくあなた自身の実装のどれでも同じことをするべきです。)