Dave
Dave

Reputation: 3717

Can't add keyValuePair directly to Dictionary

I wanted to add a KeyValuePair<T,U> to a Dictionary<T, U> and I couldn't. I have to pass the key and the value separately, which must mean the Add method has to create a new KeyValuePair object to insert, which can't be very efficient. I can't believe there isn't an Add(KeyValuePair<T, U>) overload on the Add method. Can anyone suggest a possible reason for this apparent oversight?

Upvotes: 53

Views: 44365

Answers (8)

WiiMaxx
WiiMaxx

Reputation: 5420

Should somebody really want to do this, here is an Extension

    public static void Add<T, U>(this IDictionary<T, U> dic, KeyValuePair<T, U> KVP)
    {
        dic.Add(KVP.Key, KVP.Value);
    }

but i would recommend to not do this if there is no real need to do this

Upvotes: 3

DmitryG
DmitryG

Reputation: 17848

You can use the IDictionary<TKey,TValue> interface which provides the Add(KeyValuePair<TKey,TValue>) method:

IDictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(new KeyValuePair<int,string>(0,"0"));
dictionary.Add(new KeyValuePair<int,string>(1,"1"));

Upvotes: 51

Machtyn
Machtyn

Reputation: 3282

Unless I'm mistaken, .NET 4.5 and 4.6 adds the ability to add a KeyValuePair to a Dictionary. (If I'm wrong, just notify me and I'll delete this answer.)

https://msdn.microsoft.com/en-us/library/cc673027%28v=vs.110%29.aspx

From the above link, the relevant piece of information is this code example:

public static void Main() 
{
    // Create a new dictionary of strings, with string keys, and 
    // access it through the generic ICollection interface. The 
    // generic ICollection interface views the dictionary as a 
    // collection of KeyValuePair objects with the same type 
    // arguments as the dictionary. 
    //
    ICollection<KeyValuePair<String, String>> openWith =
        new Dictionary<String, String>();

    // Add some elements to the dictionary. When elements are  
    // added through the ICollection<T> interface, the keys 
    // and values must be wrapped in KeyValuePair objects. 
    //
    openWith.Add(new KeyValuePair<String,String>("txt", "notepad.exe"));
    openWith.Add(new KeyValuePair<String,String>("bmp", "paint.exe"));
    openWith.Add(new KeyValuePair<String,String>("dib", "paint.exe"));
    openWith.Add(new KeyValuePair<String,String>("rtf", "wordpad.exe"));

    ...
}

As can be seen, a new object of type Dictionary is created and called openWith. Then a new KVP object is created and added to openWith using the .Add method.

Upvotes: 2

Machtyn
Machtyn

Reputation: 3282

What would be wrong with just adding it into your project as an extension?

namespace System.Collection.Generic
{
    public static class DictionaryExtensions
    {
        public static void AddKeyValuePair<K,V>(this IDictionary<K, V> me, KeyValuePair<K, V> other)
        {
            me.Add(other.Key, other.Value);
        }
    }
}

Upvotes: 0

Richard
Richard

Reputation: 109200

There is such a method – ICollection<KeyValuePair<K, T>>.Add but as it is explicitly implemented you need to cast your dictionary object to that interface to access it.

((ICollection<KeyValuePair<KeyType, ValueType>>)myDict).Add(myPair);

See

The page on this method includes an example.

Upvotes: 18

Mike Corcoran
Mike Corcoran

Reputation: 14564

just because the enumerator for the Dictionary class returns a KeyValuePair, does not mean that is how it is implemented internally.

use IDictionary if you really need to pass KVP's because you've already got them in that format. otherwise use assignment or just use the Add method.

Upvotes: 1

Tim Copenhaver
Tim Copenhaver

Reputation: 3302

Backup a minute...before going down the road of the oversight, you should establish whether creating a new KeyValuePair is really so inefficient.

First off, the Dictionary class is not internally implemented as a set of key/value pairs, but as a bunch of arrays. That aside, let's assume it was just a set of KeyValuePairs and look at efficiency.

The first thing to notice is that KeyValuePair is a structure. The real implication of that is that it has to be copied from the stack to the heap in order to be passed as a method parameter. When the KeyValuePair is added to the dictionary, it would have to be copied a second time to ensure value type semantics.

In order to pass the Key and Value as parameters, each parameter may be either a value type or a reference type. If they are value types, the performance will be very similar to the KeyValuePair route. If they are reference types, this can actually be a faster implementation since only the address needs to be passed around and very little copying has to be done. In both the best case and worst case, this option is marginally better than the KeyValuePair option due to the increased overhead of the KeyValuePair struct itself.

Upvotes: 42

Gertjan Assies
Gertjan Assies

Reputation: 1900

I'm not 100% sure, but I think the internal implementation of a Dictionary is a Hash-table, which means key's are converted to hashes to perform quick look ups.

Have a read here if you want to know more about hashtables

http://en.wikipedia.org/wiki/Hash_table

Upvotes: -2

Related Questions