There doesn't appear to be a generic implementation of OrderedDictionary
(which is in the System.Collections.Specialized
namespace) in .NET 3.5. Is there one that I'm missing?
I've found implementations out there to provide the functionality, but wondered if/why there isn't a generic implementation out-of-the-box and if anyone knows whether it's something in .NET 4.0?
I implemented generic
OrderedDictionary<TKey, TValue>
by wraping aroundSortedList<TKey, TValue>
and adding privateDictionary<TKey, int>
_order
. Then I created internal implementation ofComparer<TKey>
passing reference to the _order dictionary. Then I use this comparer for internal SortedList. This class keeps order of elements passed to constructor and order of additions.This implementation has almost the same BigO characteristics as
SortedList<TKey, TValue>
since Adding and Removing to _order is O(1). Each element will take (according to the book 'C# 4 in a Nutshell', p. 292, table 7-1) additional memory space of 22 (overhead) + 4 (int order) + TKey size (let assume 8) = 34. Together withSortedList<TKey, TValue>
overhead of 2 bytes the total overhead is 36 bytes, while the same book says that non-genericOrderedDictionary
has overhead of 59 bytes.If I pass
sorted=true
to constructor, then _order is not used at all, theOrderedDictionary<TKey, TValue>
is exactlySortedList<TKey, TValue>
with minor overhead for wrapping, if at all meaningful.I am going to store not-so-many large reference objects in the
OrderedDictionary<TKey, TValue>
, so for me this c.36 bytes overhead is tolerable.The main code is below. The complete updated code is on this gist.
As a follow up to the comment from @V.B. here's an accessible implementation of the System.Runtime.Collections.OrderedDictionary<,>. I was originally going to access it by reflection and provide it via a factory but the dll this is in does not seem to be very accessible at all so I just pulled the source itself.
One thing to note is the indexer here will not throw
KeyNotFoundException
. I absolutely hate that convention and that was the 1 liberty i took in this implementation. If that's important to you, just replace the line forreturn default(TValue);
. Uses C# 6 (compatible with Visual Studio 2013)Pull requests/discussion accepted on GitHub
You're right. There's no generic equivalent of
OrderedDictionary
in the framework itself.(That's still the case for .NET4 too, as far as I'm aware.)
EDIT: But you can vote for it at Visual Studio's UserVoice!
Implementing a generic
OrderedDictionary
isn't terribly difficult, but it's unnecessarily time consuming and frankly this class is a huge oversight on Microsoft's part. There are multiple ways of implementing this, but I chose to use aKeyedCollection
for my internal storage. I also chose to implement various methods for sorting the way thatList<T>
does since this is essentially a hybrid IList and IDictionary. I've included my implementation here for posterity.Here's the interface. Notice that it includes
System.Collections.Specialized.IOrderedDictionary
, which is the non-generic version of this interface that was provided by Microsoft.Here's the implementation along with helper classes:
And no implementation would be complete without a few tests (but tragically, SO won't let me post that much code in one post), so I'll have to leave you to write your tests. But, I left a few of them in so that you could get an idea of how it works:
-- UPDATE --
Source for this and other really useful missing core .NET libraries here: https://github.com/mattmc3/dotmore/blob/master/dotmore/Collections/Generic/OrderedDictionary.cs
Right, it's an unfortunate omission. I miss Python's OrderedDict
So I wrote my own
OrderedDictionary<K,V>
class in C#. How does it work? It maintains two collections - a vanilla unordered dictionary and an ordered list of keys. With this solution, the standard dictionary operations keep their fast complexities, and look up by index is fast too.https://gist.github.com/hickford/5137384
Here's the interface