Встроенный список, к которому можно получить доступ по индексу и ключу

Можно ли создать список, к которому можно получить доступ либо по индексу, либо по ключу?

Я ищу тип коллекции, который уже существует, но имеет эту возможность, я хочу избежать переопределения индексаторов


person Graviton    schedule 18.11.2008    source источник
comment
Определите индекс и ключ. Опубликуйте синтаксис, который вы хотите написать.   -  person Robert Wagner    schedule 18.11.2008
comment
Когда вы говорите «создать», вы хотите создать новый тип коллекции с этой возможностью или вы ищете тип коллекции, который уже существует, но имеет эту возможность?   -  person Martin Brown    schedule 18.11.2008


Ответы (5)


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
person Martin Brown    schedule 18.11.2008

Существующие ответы уже показывают, как добавить свои собственные индексаторы.

Возможно, вы захотите взглянуть на некоторые из существующих коллекций на основе ключей, таких как SortedList<,>, который действует аналогично Dictionary<,>, но позволяет использовать индексатор ключа и позиции.

Кроме того, вы должны иметь возможность использовать наследование для большинства вещей такого типа, например, наследование от Collection<> или List<>. Обратите внимание, что если ваша коллекция реализует IList/IList<T>, я не рекомендую следующее (что я иногда вижу):

public SomeType this[int someId] {...}

Дело в том, что люди ожидают, что целочисленный индексатор IList[<T>] будет позиционным.

person Marc Gravell    schedule 18.11.2008

Аналогичный вопрос есть в Какая структура данных в .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);
    }
 }
person Mark Cidade    schedule 18.11.2008

public object this[int index]
{
    get { ... }
    set { ... }
}

Помимо создания целочисленного индекса, вы можете указать ключ любого другого типа, который вам нравится.

public object this[String key]
{
    get { ... }
    set { ... }
}

Если вы не хотите определять свою собственную коллекцию, просто наследуйте от List<T> или просто используйте переменную типа List<T>.

person Mark Ingram    schedule 18.11.2008

Вы можете добавить индексатор, добавив в свою коллекцию следующее свойство:

public object this[int index]
{
    get { /* return the specified index here */ }
    set { /* set the specified index to value here */ }
}

Это можно быстро добавить в Visual Studio, введя indexer и нажав [tab] [tab].

Конечно, тип возвращаемого значения и тип индексатора можно изменить. Вы также можете добавить несколько типов индексаторов.

person Robert Wagner    schedule 18.11.2008