Is it possible to create a list that can be access by either an index or a key?
I am looking for a Collection type that already exists but has this facility, I want to avoid redefining the indexers
Is it possible to create a list that can be access by either an index or a key?
I am looking for a Collection type that already exists but has this facility, I want to avoid redefining the indexers
You can add an indexer by adding the following property to your collection:
public object this[int index]
{
get { /* return the specified index here */ }
set { /* set the specified index to value here */ }
}
This can be quickly added in Visual Studio by typing indexer and pressing [tab] [tab].
The return type and indexer type can be changed ofcourse. You can also add multiple indexer types.
public object this[int index]
{
get { ... }
set { ... }
}
As well as doing just an integer index, you can provide a key of any other type you like
public object this[String key]
{
get { ... }
set { ... }
}
If you don't want to define your own collection, just inherit from List<T>
, or just use a variable of type List<T>
.
System.Collections.Specialized.NameValueCollection can do this, but it can only store strings as values.
System.Collections.Specialized.NameValueCollection k =
new System.Collections.Specialized.NameValueCollection();
k.Add("B", "Brown");
k.Add("G", "Green");
Console.WriteLine(k[0]); // Writes Brown
Console.WriteLine(k["G"]); // Writes Green
Existing answers already show how to add your own indexers.
You might want to look at some of the existing key-based collections, such as SortedList<,>
, which acts similarly to Dictionary<,>
, but allows key and position indexer usage.
Also - you should be able to use inheritance for much of this type of thing - for example, inheriting from Collection<>
or List<>
. Note that if your collection implements IList
/IList<T>
, I don't recommend the following (which I see occasionally):
public SomeType this[int someId] {...}
The point is, people expect the integer indexer of an IList[<T>]
to be positional.
There's a similar question at http://stackoverflow.com/questions/137753/what-is-the-best-data-structure-in-net-for-look-up-by-string-key-or-numeric-ind.
Have a look at KeyedCollection:
class IndexableDictionary<TKey, TItem> : KeyedCollection<TKey, TItem>
{ Dictionary<TItem, TKey> keys = new Dictionary<TItem, TKey>();
protected override TKey GetKeyForItem(TItem item) { return keys[item];}
public void Add(TKey key, TItem item)
{ keys[item] = key;
this.Add(item);
}
}