The short answer is that there shouldn't be a way since a Dictionary "Represents a collection of keys and values." which does not imply any sort of ordering. Any hack you might find is outside the definition of the class and may be liable to change.
You should probably first ask yourself if a Dictionary is really called for in this situation, or if you can get away with using a List of KeyValuePairs.
Otherwise, something like this might be useful:
public class IndexableDictionary<T1, T2> : Dictionary<T1, T2>
{
private SortedDictionary<int, T1> _sortedKeys;
public IndexableDictionary()
{
_sortedKeys = new SortedDictionary<int, T1>();
}
public new void Add(T1 key, T2 value)
{
_sortedKeys.Add(_sortedKeys.Count + 1, key);
base.Add(key, value);
}
private IEnumerable<KeyValuePair<T1, T2>> Enumerable()
{
foreach (T1 key in _sortedKeys.Values)
{
yield return new KeyValuePair<T1, T2>(key, this[key]);
}
}
public new IEnumerator<KeyValuePair<T1, T2>> GetEnumerator()
{
return Enumerable().GetEnumerator();
}
public KeyValuePair<T1, T2> this[int index]
{
get
{
return new KeyValuePair<T1, T2> (_sortedKeys[index], base[_sortedKeys[index]]);
}
set
{
_sortedKeys[index] = value.Key;
base[value.Key] = value.Value;
}
}
}
With client code looking something like this:
static void Main(string[] args)
{
IndexableDictionary<string, string> fooDict = new IndexableDictionary<string, string>();
fooDict.Add("One", "One");
fooDict.Add("Two", "Two");
fooDict.Add("Three", "Three");
// Print One, Two, Three
foreach (KeyValuePair<string, string> kvp in fooDict)
Console.WriteLine(kvp.Value);
KeyValuePair<string, string> temp = fooDict[1];
fooDict[1] = fooDict[2];
fooDict[2] = temp;
// Print Two, One, Three
foreach (KeyValuePair<string, string> kvp in fooDict)
Console.WriteLine(kvp.Value);
Console.ReadLine();
}
UPDATE: For some reason it won't let me comment on my own answer.
Anyways, IndexableDictionary is different from OrderedDictionary in that
- "The elements of an OrderedDictionary are not sorted in any way." So foreach's would not pay attention to the numerical indices
- It is strongly typed, so you don't have to mess around with casting things out of DictionaryEntry structs