我有一个充当字典的 C# 类,所以我现在正在支持 IDictionary。
一切都很好,除了属性键和值:
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 ...
这太糟糕了,因为这将是最简单的解决方案!
我的第二次尝试是将我的值复制到一个新创建的数组中并返回该数组。
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,这样我就可以从属性 Keys 和 Values 中返回这些集合......
public class MyDictionary : IDictionary<TKey,TValue>,
ICollection<TKey>,
ICollection<TValue>
{
}
所以现在属性 Keys 和 Values 的 get 访问器只返回“this”,即:字典。
ICollection<TValue> Values {
get {
return this;
}
}
这可能是最理想的解决方案,但我发现无论何时要实现 IDictionary,都必须实现两个额外的接口很麻烦。
你有什么别的想法吗?
我在想也许将副本作为数组返回毕竟不是一个坏主意。无论如何,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);
}
}