为什么Dictionary<TKey, TValue>没有一个接受KeyValuePair对象的Add方法?

4
根据.NET API,类Dictionary<TKey, TValue>继承自ICollection<T>,其中TKeyValuePair<TKey, TValue>。那么Dictionary<TKey, TValue>类如何隐藏其从ICollection<T>继承的一些方法呢?
例如: ICollection<T>ICollection.Add(T item)方法, 但当您使用Dictionary<TKey, TValue>对象时,它没有该方法。您只能使用Dictionary<TKey, TValue>.Add(TKey key, TValue value)方法。没有Dictionary<TKey, TValue>.Add(KeyValuePair<TKey,TValue> kvp)方法。
是否有人知道为什么?这些方法被如何隐藏?
5个回答

5

谢谢,那正好回答了我的问题。以前我从未显式地实现过接口,所以我没有意识到这是显式实现的效果。 - LamdaComplex
效果并非“自动”的,只有在更改访问修饰符(例如省略任何访问修饰符)从public到private/protected时才会生效。 - Yahia

4
他们是通过显式接口实现来“隐藏”的。因此,您可以使用以下代码:
ICollection<KeyValuePair<Foo, Bar>> collection = dictionary;
collection.Add(...);

根据文档,这个方法“应该”可以工作……虽然通常最好使用其他方法。

谢谢Jon,你总是有很好的答案。我之前不知道显式接口实现,谢谢你。 - LamdaComplex

2
因为字典类(Dictionary)已经明确实现了ICollection.Add方法,所以在使用它之前需要将其强制转换为ICollection<KeyValuePair<TKey,TValue>>类型。
你可以在MSDN上查看该实现。
void ICollection<KeyValuePair<TKey, TValue>>.Add(
    KeyValuePair<TKey, TValue> keyValuePair
)

1

参考代码,显式实现 ICollection<>.Add() 方法的 Dictionary<> 代码如下:

void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> keyValuePair)
{
    this.Add(keyValuePair.Key, keyValuePair.Value);
}

你应该可以放心使用它,因为它只是在做你可能会自己做的事情。


1
如果Dictionary直接公开了一个Add(KeyValuePair<TKey,TValue>)重载,那么这意味着如果有一个KeyValuePair<TKey,TValue>(例如在枚举另一个字典时收到的),最好将其传递给这样的方法,而不是读取KeyValue属性并分别传递它们。实际上,相反是正确的:将整个结构传递给一个Add方法,然后必须将其分解并将其成员传递给离散参数重载,这比将结构分解为其成员并单独传递它们要低效。
请注意,如果Dictionary在内部存储了一个结构类型的数组,该数组具有KeyValuePair<TKey,TValue>作为字段(而不是属性),则像下面这样的代码:
for var item in Dict1
{
  Dict2.Add(item);
}

可能比...更有效率

for var item in Dict1
{
  Dict2.Add(item.Key, Item.Value);
}

但是由于Dictionary会分解任何传入的KeyValuePair,因此没有理由鼓励前一种代码风格。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接