【发布时间】:2013-02-07 16:23:25
【问题描述】:
我有一个用作字典的 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);
}
}
【问题讨论】:
-
你的课与 Dictionary
有何不同?
标签: c# key-value icollection idictionary