Преобразовать словарь <MyType>.ValueCollection в IList <MyType> - PullRequest
16 голосов
/ 29 марта 2010

Я использую Dictionary<int, MyType> в классе. Этот класс реализует интерфейс, требующий возврата IList<MyType>. Есть ли простой способ приведения одного к другому (без копирования всей вещи)?

Мое текущее решение следующее:

private IList<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection)
{
    List<MyType> list = new List<MyType>();
    list.AddRange(valueCollection);
    return list;
}

Ответы [ 4 ]

26 голосов
/ 29 марта 2010

Вам нужно будет сделать копию, но это, вероятно, хорошая вещь. В C # 2 ваш текущий код почти самый чистый, который вы можете сделать. Это было бы улучшено путем непосредственного создания списка из ваших значений (List<MyType> list = new List<MyType>(valueCollection);), но копия все равно потребуется.

Используя LINQ с C # 3, вы сможете:

myDictionary.Values.ToList();

При этом я бы не стал (вероятно) пытаться избежать копирования. Возврат копии ваших значений имеет тенденцию быть более безопасным, так как это предотвращает проблемы вызывающих абонентов, если они пытаются изменить вашу коллекцию. Возвращая копию, вызывающий абонент может выполнить list.Add(...) или list.Remove(...), не вызывая проблем в классе.


Редактировать: Учитывая ваш комментарий ниже, если все, что вам нужно, это IEnumerable<T> с Count, вы можете просто вернуть ICollection<T>. напрямую реализован ValueCollection, что означает, что вы можете просто возвращать значения словаря напрямую, без копирования:

private ICollection<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection)
{
    return valueCollection;
}

(Конечно, этот метод становится действительно бесполезным в этом случае - но я хотел продемонстрировать это для вас ...)

3 голосов
/ 29 марта 2010

Как насчет

Dictionary<int, MyType> dlist = new Dictionary<int, MyType>();
IList<MyType> list = new List<MyType>(dlist.Values);
2 голосов
/ 29 марта 2010

Это невозможно.

Словарь (включая его коллекцию Values) - это изначально неупорядоченные коллекции;его порядок будет меняться в зависимости от хеш-кодов его ключей.Вот почему ValueCollection не реализует IList<T>.

Если бы вы действительно хотели, вы могли бы создать класс-оболочку, который реализует IList и обернетValueCollection, используя цикл foreach в индексаторе.Однако это не очень хорошая идея.

0 голосов
/ 29 марта 2010

Вы можете использовать конструктор:

public IList<MyType> MyValues
{
    get { return new List<MyType>(myDictionary.Values); }
}

(Отредактировано для удаления утверждения, в котором я не уверен на 100%.)

...