2012-06-11 4 views
5
// No overrides required .. let CLR take care of equal and hashcode. 
Class Foo {public Name{get; set;} public Address{get; set;}} 

Dictionary<List<Foo>, int> map = new Dictionary<List<Foo>, int>(); 

Вопрос:Могу ли я использовать Список объектов в качестве словарных ключей?

Является ли этот код выглядеть хорошо? Я понимаю, что для того, чтобы быть ключом на карте, Foo должен переопределить методы equals и hashcode - либо переопределить оба, либо none.

Мне было интересно, что относительно списка объектов как ключей? Что означает равенство, когда дело доходит до Списка? - это карта, определенная выше, безопасная от проблемы «объект-потеря-в-карте»?

-Karephul

ответ

3
List<int> a = new List<int>(1, 2, 3); 
List<int> b = new List<int>(1, 2, 3); //different instance than a 

Dictionary<List<int>, int>> map = new Dictionary<List<int>, int>>(); 
map.Add(a, a.Sum()); 
int aSum = map[b]; //KeyNotFoundException because this is a different instance. 


HashSet<int> a = new HashSet<int>(1, 2, 3); 
HashSet<int> b = new HashSet<int>(1, 2, 3); //different instance than a 

Dictionary<HashSet<int>, int>> map1 = new Dictionary<HashSet<int>, int>>(); 
map1.Add(a, a.Sum()); 
int aSum = map1[b]; //KeyNotFoundException because this is a different instance. 


HashSet<int> a = new HashSet<int>(1, 2, 3); 
HashSet<int> b = new HashSet<int>(1, 2, 3); //different instance than a 

Dictionary<HashSet<int>, int>> map2 = new Dictionary<HashSet<int>, int>> 
    (HashSet<int>.CreateSetComparer()); //instance comparison not used - equal sets are equal 
map2.Add(a, a.Sum()); 
int aSum = map2[b]; //6 
+0

+ 1 для примеров – karephul

5

Это будет работать только если вы используете оригинальные List<T> экземпляры в качестве ключей.
Если вы создаете новый List<T> с теми же товарами, он не будет считаться одним и тем же ключом, поскольку List<T> не переопределяет Equals() и GetHashCode().

Иными словами, он будет использовать ссылочное равенство.

Если вы хотите изменить это, вы можете написать IEqualityComparer<List<T>>.

+0

+ 1 для хорошего ответа. – karephul

0

Конечно, вы могли, но это было бы невероятно ограничено. Проще говоря, список комбинации Foo, даже если элементы списка все одинаковы Foo, необязательно то же самое List<Foo>. Таким образом, вам нужно будет поддерживать ссылки в некоторых недвусмысленных выражениях, чтобы убедиться, что ключ один и тот же, или сделать сложную функцию сопоставления клавиш.

Это было бы далеко, далеким лучше просто использовать лучший тип ключа.

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