Можно ли создать список, к которому можно получить доступ либо по индексу, либо по ключу?
Я ищу тип коллекции, который уже существует, но имеет эту возможность, я хочу избежать переопределения индексаторов
Можно ли создать список, к которому можно получить доступ либо по индексу, либо по ключу?
Я ищу тип коллекции, который уже существует, но имеет эту возможность, я хочу избежать переопределения индексаторов
System.Collections.Specialized.NameValueCollection может сделать это, но может хранить только строки в качестве значений.
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
Существующие ответы уже показывают, как добавить свои собственные индексаторы.
Возможно, вы захотите взглянуть на некоторые из существующих коллекций на основе ключей, таких как SortedList<,>
, который действует аналогично Dictionary<,>
, но позволяет использовать индексатор ключа и позиции.
Кроме того, вы должны иметь возможность использовать наследование для большинства вещей такого типа, например, наследование от Collection<>
или List<>
. Обратите внимание, что если ваша коллекция реализует IList
/IList<T>
, я не рекомендую следующее (что я иногда вижу):
public SomeType this[int someId] {...}
Дело в том, что люди ожидают, что целочисленный индексатор IList[<T>]
будет позиционным.
Аналогичный вопрос есть в Какая структура данных в .NET лучше всего подходит для поиска по строковому ключу или числовому индексу?.
Взгляните на 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);
}
}
public object this[int index]
{
get { ... }
set { ... }
}
Помимо создания целочисленного индекса, вы можете указать ключ любого другого типа, который вам нравится.
public object this[String key]
{
get { ... }
set { ... }
}
Если вы не хотите определять свою собственную коллекцию, просто наследуйте от List<T>
или просто используйте переменную типа List<T>
.
Вы можете добавить индексатор, добавив в свою коллекцию следующее свойство:
public object this[int index]
{
get { /* return the specified index here */ }
set { /* set the specified index to value here */ }
}
Это можно быстро добавить в Visual Studio, введя indexer и нажав [tab] [tab].
Конечно, тип возвращаемого значения и тип индексатора можно изменить. Вы также можете добавить несколько типов индексаторов.