Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use List of objects as Dictionary Keys ?

Tags:

c#

// 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>();

Question:

Is this code look alright ? I understand that to be a key in the Map, Foo needs to override equals and hashcode methods - either override both or none.

I was wondering what about List of objects as keys ? What does equality means when it comes to List ? is the map defined above safe from "object-lost-in-the-map" problem ?

-Karephul

like image 263
karephul Avatar asked Jun 11 '12 21:06

karephul


People also ask

Can you use lists as dictionary keys?

Second, a dictionary key must be of a type that is immutable. For example, you can use an integer, float, string, or Boolean as a dictionary key. However, neither a list nor another dictionary can serve as a dictionary key, because lists and dictionaries are mutable.

Why lists cant be used as dictionary keys?

You cannot use a list as a key because a list is mutable. Similarly, you cannot use a tuple as a key if any of its elements are lists. (You can only use a tuple as a key if all of its elements are immutable.)

Can a list be an item in a dictionary?

It definitely can have a list and any object as value but the dictionary cannot have a list as key because the list is mutable data structure and keys cannot be mutable else of what use are they.


2 Answers

This will only work if you use the original List<T> instances as keys.
If you create a new List<T> with the same items, it will not be treated as the same key, since List<T> does not override Equals() and GetHashCode().

In other words, it will use reference equality.

If you want to change that, you can write an IEqualityComparer<List<T>>.

like image 144
SLaks Avatar answered Sep 25 '22 18:09

SLaks


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
like image 23
Amy B Avatar answered Sep 24 '22 18:09

Amy B