views:

133

answers:

5

I made a Dictionary<string, string> collection so that I can quickly reference the items by their string identifier.

But I now also need to access this collective by index counter (foreach won't work in my real example).

What do I have to do to the collection below so that I can access its items via integer index as well?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestDict92929
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, string> events = new Dictionary<string, string>();

            events.Add("first", "this is the first one");
            events.Add("second", "this is the second one");
            events.Add("third", "this is the third one");

            string description = events["second"];
            Console.WriteLine(description);

            string description = events[1]; //error
            Console.WriteLine(description);
        }
    }
}
+13  A: 

You can't. And your question infers your belief that Dictionary<TKey, TValue> is an ordered list. It is not. If you need an ordered dictionary, this type isn't for you.

Perhaps OrderedDictionary is your friend. It provides integer indexing.

Andrew Arnott
exactly what I was looking for, thanks
Edward Tanguay
+2  A: 

You can't: an index is meaningless because a dictionary is not ordered - and the order in which items are returned when enumerating can change as you add and remove items. You need to copy the items to a list to do that.

Joe
+2  A: 

Dictionary is not sorted/ordered, so index numbers would be meaningless.

David Pfeffer
You're thinking of it backwards. Think of it as primarily a `List` but with methods like Insert, Remove, IndexOf - but instead of just adding items and retrieving via an integer indexer, you can get to them via some other way too - typically a string. The `DataRow` class in a DataTable functions somewhat like this.
mattmc3
+4  A: 

You can not. As was said - a dictionary has no order.

Make your OWN CONTAINER that exposes IList and IDictionary... and internally manages both (list and dictionary). This is what I do in those cases. So, I can use both methods.

Basically

class MyOwnContainer : IList, IDictionary

and then internally

IList _list = xxx IDictionary _dictionary = xxx

then in add / remove / change... update both.

TomTom
+2  A: 

You can use the KeyedCollection<TKey, TItem> class in the System.Collections.ObjectModel namespace for this. There's only one gotcha: it is abstract. So you will have to inherit from it and create your own :-). Otherwise use the non-generic OrderedDictionary class.

Steven
+1 for KeyedCollection
Joel Coehoorn