62

I know that its possible to convert a List of KeyValuePair into a Dictionary, but is there a quick way (besides looping through manually) to perform the vice versa operation?

This would be the manual way,

foreach (KeyValuePair<double,double> p in dict)
{
    list.Add(new KeyValuePair<double,double>(p.Key,p.Value));
}

Not really that bad but I was just curious.

Sean
  • 769
  • 2
  • 8
  • 7
  • 3
    you don't need to create new KeyValuePairs; this is much simpler: `foreach (KeyValuePair p in dict) { list.Add(p); }` – phoog Dec 29 '10 at 20:48

5 Answers5

142

To convert a Dictionary<TKey, TValue> to a List<KeyValuePair<TKey, TValue>> you can just say

var list = dictionary.ToList();

or the more verbose

var list = dictionary.ToList<KeyValuePair<TKey, TValue>>();

This is because Dictionary<TKey, TValue> implements IEnumerable<KeyValuePair<TKey, TValue>>.

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
jason
  • 236,483
  • 35
  • 423
  • 525
8

Using linq:

myDict.ToList<KeyValuePair<double, double>>();

Dictionary elements are KeyValuePair items.

johnny 5
  • 19,893
  • 50
  • 121
  • 195
Oded
  • 489,969
  • 99
  • 883
  • 1,009
8

Like Jason said. But if you don't really need a list, then you can just cast it to an ICollection<TKey, TValue>; because it implements this interface, but some parts only explicitly. This method performs better because it don't copy the entire list, just reuses the same dictionary instance.

d219
  • 2,707
  • 5
  • 31
  • 36
fejesjoco
  • 11,763
  • 3
  • 35
  • 65
  • `ToList` merely copies the references to the dictionary items. This is blazingly fast and highly unlikely to be a relevant performance issue. – jason Dec 29 '10 at 19:44
  • 2
    Casting is infinitely faster. Which isn't noticeable if you do it only a few times with small lists, but still, it does matter a lot. – fejesjoco Dec 29 '10 at 19:52
  • 1
    @Jason: Not true. A call to the extensionmethod Enumerable.ToList> is potentially expensive. From another perspective, it must return a new list, otherwise you could add items to the dictionary by adding items to the list, which would be weird. – JBSnorro Dec 29 '10 at 19:55
  • @JBSnorro: I don't know what you're talking about. Creating a new list and copying references is cheap. – jason Dec 29 '10 at 20:09
  • @Jason: and casting is effectively zero compared to that. – fejesjoco Dec 29 '10 at 20:10
  • @fejesjoco: That's a micro-optimization as performance is almost surely completely irrelevant here. – jason Dec 29 '10 at 20:13
  • 3
    Why do people keep calling these things unnecessary micro-optimizations? How do you know he won't run it a thousand times with lists that contain a million elements? Isn't it always better to learn and do things the best possible way? Is it better if he learns software programming while not giving a * about these things? Well, not my problem, this way I know I'll always have a job. – fejesjoco Dec 29 '10 at 20:20
  • 1
    @fejesjoco: I feel a rant coming on. – jason Dec 29 '10 at 20:38
  • 5
    @fejesjoco: Because people are enslaved to cycles and bytes like it's still 1980. There is in general too much emphasis on performance first over clarity of code and other concerns. Performance isn't the be all end all anymore (with mobile devices, for example, we should optimize for power consumption, not performance!) I don't know that he won't run it a thousand times with lists that contain a million elements, but I suspect that he won't be. And if he is, I still doubt it matters. And even if it does matter, he's got bigger issues to worry about because he's doing something wrong. – jason Dec 29 '10 at 20:39
  • @fejesjoco: This is a micro-optimization. Period. If it matters, something is seriously wrong with big upfront design stuff. – jason Dec 29 '10 at 20:39
  • 1
    @Jason: KeyValuePair is a struct, so you're only copying references if your keys or values are reference types. Otherwise, you're copying values. And the original example uses value types. – phoog Dec 29 '10 at 20:47
  • @phoog: First, he's using `double`. Copying `double`s is ridiculously fast. Second, if he's using a value type where copying speed becomes relevant, something is probably wrong. – jason Dec 29 '10 at 21:02
  • @Jason, I didn't mean to take issue with your statement that the copying in ToList() is blazingly fast. I just meant to point out that KeyValuePair is a value type, not a class. – phoog Dec 29 '10 at 21:09
  • I like Jason's answer. The big picture is always more important. And the big picture isn't necessarily performance. – surfasb Jun 21 '11 at 23:11
  • 3
    You guys are talking about this optimization like it's unreadable or somehow less powerful or something, that's ridiculous. If all you need is a collection, this works great and is the preferred approach, you do not sacrifice any readability and it is infinitely faster (in the few edge cases where that might matter). This is not an unnecessary micro-optimization, it's just good practice. OTOH, If you *need* a list, take the hit and call .ToList(); -- Either way, your code is easy to read, and probably about as fast as it can be without sacrificing readability. – BrainSlugs83 Jun 11 '14 at 02:17
  • These days cycles are almost free. The argument of "performance not being an issue anymore" made them even came up with game and render engines based on C#. AAA games may still incur millions of objects at 60-90 fps. This poses a challenge even with C/C++. C#/.NET was built with the advantage of ease and clarity over C++ at the cost of performance and it's ok, since C# was not meant for AAA games in the first place. So C#/games mix as uninspired, is enough justification for any available optimization. Please, don't condemn optimizations, let the users decide for themselves. – mireazma Sep 23 '20 at 17:07
0

For .NET 2.0:

Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();
List<KeyValuePair<TKey, TValue>> myList = new List<KeyValuePair<TKey, TValue>>(dictionary);
Daniel Bogdan
  • 758
  • 10
  • 23
0

I've been trying enumerate an instance of Exception.Data which is an IDictionary. This is what finally worked:

    ICollection keys = idict.Keys;
    foreach(var key in keys)
    {
       var value = idict[key];
       Console.WriteLine("{0}: {1}", key, value);
    }
Schwarrior
  • 211
  • 2
  • 2