Словарь с ключом списка <T> - PullRequest
3 голосов
/ 30 марта 2012

Я столкнулся с небольшой проблемой, используя List в качестве ключа в словаре (). Вот мой пример кода, который иллюстрирует проблему:

Dictionary<List<double>, string> test = new Dictionary<List<double>, string>();
var a = new List<double>() { 1.0 };
var b = new List<double>() { 2.0 };

test.Add(a, "A");
test.Add(b, "B");

// Works because the reference is the same
Console.WriteLine(test[a]);

// KeyNotFoundException
Console.WriteLine(test[new List<double>() { 1.0 }]);

Я знаю, что это ошибки, потому что Словарь использует ссылку на список, а не содержимое списка. В идеале следует использовать SequenceEquals, чтобы определить, существует ли ключ, если TKey является списком.

Есть идеи как обойти это? Есть ли другая коллекция, которую я мог бы использовать? Должен ли я просто создать новый класс-оболочку, SequenceDictionary?

Ответы [ 2 ]

4 голосов
/ 30 марта 2012

Вам необходимо указать пользовательский компаратор для словаря. Конструктор словаря принимает перегрузку с дополнительным параметром IEqualityComparer<List<double>>. Тогда вам просто нужно создать класс с методом Compare, который может сравнивать два List<double> s. Вам также потребуется предоставить метод GetHashCode, использующий этот

Другой вариант - найти ключ, отличный от списка. Списки не создают хороших ключей по нескольким причинам:

  • Вы не можете быстро сравнить два списка. Метод сравнения - O (n).
  • Вы не можете быстро вычислить хэш списка; вам нужно использовать все элементы в списке для создания соответствующего хэша.
  • Если список изменяется, пока он находится внутри словаря, хэш-код изменится, и это сломает все виды вещей. Список потребностей быть неизменным, пока он является ключом в словаре.
2 голосов
/ 30 марта 2012

Либо так, либо создайте свой собственный класс ключей, производный от List<double> и реализующий IComparable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...