views:

130

answers:

4

What I want is basically a collection that's a hybrid of a dictionary and a list. I want a collection that I can add key/value pairs to (like a Dictionary), but at the same be able to retrieve the values (without the keys) in the same order I added them (like a List)? Does such a collection exists in .NET?

Thanks

A: 

No, there's nothing in the framework which implements this functionality at the moment (but see edit below).

Basically you would want to compose a List<T> and a Dictionary<TKey, TValue> in your own class.

EDIT: I had genuinely forgotten about OrderedDictionary as pointed out by wesleyhill - but I don't believe there's a generic collection in the framework like this. I assume you'd actually want a generic collection? You could write a wrapper around OrderedDictionary of course...

EDIT: Quick note: while wrapping the collection shouldn't be hard at all, you'll lose one benefit of generic collections: avoiding boxing. Not an issue if your keys and values are reference types, of course.

Jon Skeet
Thanks Jon ....
Truly
I beg to differ; please see my answer to this question.
Wesley Hill
Jon, you can do better: http://stackoverflow.com/questions/486948/linkedhashmap-in-c-3-0 (have a look at your answer)
atamanroman
@wesleyhill: I'd forgotten about that, but I assume the OP wants a generic collection anyway, in which case they'd at least need to wrap this. @fielding: Yeah, I don't really have time for that at the moment :)
Jon Skeet
+13  A: 

There is a non-generic data-structure called OrderedDictionary which does what you want. It has two indexers, one which takes an Object and does the key/value lookup, and one which takes an int and does an index lookup. You can also enumerate the contents in the order in which you added them.

I don't see anything in the documentation though about whether the dictionary lookup achieves O(1) (i.e. fast) behaviour. Given that it implements ISerializable it's highly likely that it uses objects' hash codes, and hence has O(1) dictionary lookup.

You could also create your own generic type which encapsulates both a List<T> and a Dictionary<TKey,TValue>.

Wesley Hill
I definatly have an old implementation of this in VB.NET and may have a newer version in C# if you are interested? The TValue is stored in a `List<TValue>` while there is a dictionary used for key to index lookup `Dictionary<TKey, int>`.
Stevo3000
This is actually what I need, except that I'm looking for a generic collection. But I might use that one after all. Thanks very much.
Truly
You just outscored Jon Skeet's answer. OMG
Tamás Szelei
A: 
  • Create a new class which wraps dictionary
  • when adding data, wrap the data in a little helper class which introduces an index
  • when returning the values, order them according the index

wouldnt be a performance monster but should work fine. Otherwise you could implement your own LinkedHashMap as in Java.

By the way, have a look at this: http://stackoverflow.com/questions/486948/linkedhashmap-in-c-3-0

edit: I do like wesleyhills idea even more: encapsulate List and Dictionary in one class. Add always to both and return the List instead of Dictionary.Values.

atamanroman
A: 

System.Collections.ObjectModel.KeyedCollection is very close to what you're asking for, except the dictionary key must be derivable from the value.

Matt Z