2012-03-30 5 views
3

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

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 - это List.

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

+0

Итак, почему вы не можете сделать это, не создав экземпляр первым? – evasilchenko

+0

Напишите свой собственный класс для ex 'IList' (используя' List') и переопределите 'Equals' и' GetHashCode' –

+0

@DeviantSeev: Если я делаю 'var c = new List () {1.0};' then 'test [c] 'исключение все еще бросается, потому что while' c = {1.0} ',' c' имеет другую ссылку. – Mark

ответ

4

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

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

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

Вы имеете в виду IEqualityComparer, а не Comparer. Но кроме этого, да :) –

+0

@JonSkeet Да, я был в процессе редактирования этого. – Servy

2

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

Смежные вопросы