Indexed Dictionary
I wanted to reference data in a dictionary based on the index order of the key without having to know the key value. So I extended Dictionary<TK,T> into DictionaryIndexable<TK, T> class which allows retrieval of values from a dictionary based on the order of keys.
Disclaimer: Please note this is not intended for general purpose use the integer type makes it too brittle for a general purpose indexable dictionary. More work and review is required to get it to that point. For instance, keys should be sortable, thus IComparable<TK> should be a generic constraint. As it is, it's broken since key sort order is undefined in the general.
You might want to consider KeyCollection if you are looking for a general purpose mechanism.
The benefits of using DictionaryIndexable instead of Dictionary is in those few and far circumstances which I've encountered more often than not in BlahBlahCollection of an ASP.NET control, where on event binding we know the index of the selected item but not the value AND it is handy to hold the control-bound data in a structure which is... well a Dictionary (which, by inheritance, DictionaryIndexable is).
It all hinges on a KeyOfIndex method which returns the key value from the Keys collection at runtime based on the index.
public class DictionaryIndexable<TK, T> : Dictionary<TK, T> { public TK KeyOfIndex(int idx) { return this.ElementAt(idx).Key;//return Keys.Skip(idx).First(); } }
Using it we can get the indexed value from a dictionary, bypassing the circumstance where the key type is integer:
public T this[int idx] { get { if (typeof(TK) == typeof(int)) { var key = (TK)Convert.ChangeType(idx, typeof(TK)); return base[key]; } return this[KeyOfIndex(idx)]; } set { if (typeof (TK) != typeof (int)) this[KeyOfIndex(idx)] = value; else { var key = (TK) Convert.ChangeType(idx, typeof (TK)); base[key] = value; } } }
What is left is to implement the IDictionary interface in order to extend the class from the Dictionary class.
Complete class:
using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; namespace System.Util { public class DictionaryIndexable<TK, T> : Dictionary<TK, T> { public static DictionaryIndexable<TK, T> FromDictionary(Dictionary<TK, T> actual) { return new DictionaryIndexable<TK, T>(actual); } public Dictionary<TK, T> ToDictionary() { return new Dictionary<TK, T>(this); } public DictionaryIndexable() : base() { } public DictionaryIndexable(SerializationInfo info, StreamingContext context) : base(info, context) { } public DictionaryIndexable(int capacity) : base(capacity) { } public DictionaryIndexable(int capacity, IEqualityComparer<TK> iEq) : base(capacity, iEq) { } public DictionaryIndexable(IDictionary<TK, T> iDic, IEqualityComparer<TK> iEq) : base(iDic, iEq) { } public DictionaryIndexable(IDictionary<TK, T> iDic) : base(iDic) { } public TK KeyOfIndex(int idx) { return this.ElementAt(idx).Key;//return Keys.Skip(idx).First(); } public T this[int idx] { get { if (typeof(TK) == typeof(int)) { var key = (TK)Convert.ChangeType(idx, typeof(TK)); return base[key]; } return this[KeyOfIndex(idx)]; } set { if (typeof (TK) != typeof (int)) this[KeyOfIndex(idx)] = value; else { var key = (TK) Convert.ChangeType(idx, typeof (TK)); base[key] = value; } } } } }









