私は辞書として機能する C# クラスを持っているので、現在 IDictionary をサポートしています。
プロパティ Keys と Values を除いて、すべて問題ありません。
ICollection<TKey> Keys { get; }
ICollection<TValue> Values { get; }
内部にキーまたは値のコレクションを持っていないので、これらを ICollection として提供する方法を考えています。
私の最初の試みは、次のような「利回り」の魔法を使用することでした。
ICollection<TValue> Values {
get {
for( int i = 0; i < nbValues; ++i ) {
yield return GetValue(i);
}
}
}
しかしもちろん、返される型は IEnumerator ではなく ICollection であるため、これは機能しません...
これが最も簡単な解決策だったので、残念です!
私の 2 番目の試みは、新しく作成した配列に値をコピーし、その配列を返すことでした。
ICollection<TValue> Values {
get {
TValue[] copy = new TValue[nbValues];
for( int i = 0; i < nbValues; ++i ) {
copy[i] = GetValue(i);
}
return copy;
}
}
Array は ICollection をサポートしているため、これは機能します。
しかし問題は、ICollection にエントリを追加および削除するメソッドがあることです。呼び出し元がこれらのメソッドを呼び出すと、辞書ではなくコピーのみが変更されます...
私が選択した最終的な解決策は、キーと値のプロパティからこれらのコレクションを返すことができるように、辞書で IDictionary だけでなく ICollection と ICollection もサポートすることです...
public class MyDictionary : IDictionary<TKey,TValue>,
ICollection<TKey>,
ICollection<TValue>
{
}
そのため、プロパティ Keys および Values の get アクセサーは単に「これ」、つまり辞書を返します。
ICollection<TValue> Values {
get {
return this;
}
}
これはおそらく最も最適なソリューションですが、IDictionary を実装するたびに 2 つの追加のインターフェイスを実装する必要があるのは面倒です。
他にアイデアはありますか?
結局のところ、コピーを配列として返すことはそれほど悪い考えではなかったと思います。とにかく、 IDictionary には、使用する方が理にかなっている Add および Remove メソッドが既にあります。
返されたコレクションを変更しようとすると失敗するため、配列をラップする ReadOnlyCollection を返す方がよいでしょうか?
ICollection<TValue> Values {
get {
TValue[] copy = new TValue[nbValues];
for( int i = 0; i < nbValues; ++i ) {
copy[i] = GetValue(i);
}
return new System.Collections.ObjectModel.ReadOnlyCollection<TValue>(copy);
}
}