4

IDictionary<TKey, TValue> extends from interface ICollection<KeyValuePair<TKey, TValue>>, so it has an Add(KeyValuePair<TKey, TValue> item) method:

IDictionary<string, object> dic = new Dictionary<string, object>();
dic.Add(new KeyValuePair<string, object>("number", 42)); // Compiles fine

However, although Dictionary<TKey, Tvalue> implements IDictionary<TKey, TValue>, it does not have this method overload:

Dictionary<string, object> dic = new Dictionary<string, object>();
dic.Add(new KeyValuePair<string, object>("number", 42)); // Does not compile

How can this be?

Matias Cicero
  • 25,439
  • 13
  • 82
  • 154

2 Answers2

5

As you can see in the documentation and in the reference source, Dictionary<TKey, TValue> implements this part of the ICollection<KeyValuePair<TKey, TValue>> interface explicitly.

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

As you have discovered, you can only call it by casting to IDictionary<TKey, TValue> or ICollection<KeyValuePair<TKey, TValue>>.

You might want to see this related question on the difference between implicit and explicit interface implementation.

Community
  • 1
  • 1
Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • 1
    Also, because anything you find in the reference source should be taken as a "Implementation detail" which could be subject to change, you can also find it in the official documentation in the "[Explicit Interface Implementations](https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx#Anchor_5)" section to get a strong contract that this fact will not change in future versions. – Scott Chamberlain Sep 30 '16 at 17:25
  • @ScottChamberlain good point - will add link to docs in answer. Thanks. – Charles Mager Sep 30 '16 at 17:25
1

If you hover over the Add method in Visual Studio, you will see that this method is coming from ICollection<T>

enter image description here

Now if you look at the http://referencesource.microsoft.com/ you will see that this method from interface ICollection<T> is explicitly implemented.

#region ICollection<KeyValuePair<TKey, TValue>> Members

void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> value)
{
    //Contract.Ensures(((ICollection<KeyValuePair<TKey, TValue>>)this).Count == Contract.OldValue(((ICollection<KeyValuePair<TKey, TValue>>)this).Count) + 1);  // not threadsafe
}

That is why it is available with IDictionary and not with Dictionary

Habib
  • 219,104
  • 29
  • 407
  • 436