Description
Trying to create a Dictionary with Tuple as the key.
However the GetHashCode and Equals functions are not being called, hence duplicate keys will be added to the dictionary.
This is the Key
class that I want to use as my Dictionary's key:
class Key : IEqualityComparer<Tuple<int, int>>
{
private Tuple<int, int> _tuple;
public Key(int a, int b)
{
_tuple = new Tuple<int, int>(a, b);
}
public bool Equals(Tuple<int, int> x, Tuple<int, int> y)
{
return (x.Item1 == y.Item1 && x.Item2 == y.Item2);
}
public int GetHashCode(Tuple<int, int> obj)
{
return obj.Item1.GetHashCode() ^ obj.Item2.GetHashCode();
}
}
Driver code:
public static void Main() {
var map = new Dictionary<Key, int>();
map.Add(new Key(1, 2), 3);
map.Add(new Key(1, 2), 4); // <==== Should not add!
}
Questions
How to fix this?
What is the easiest implementation for Dictionary<Tuple<int, int>, int>
to work properly?
If you want to use own class Key
:
public class Key
{
public Key(int item1, int item2)
{
Tuple = new Tuple<int, int>(item1, item2);
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (obj is Key other)
{
return Tuple.Equals(other.Tuple);
}
return false;
}
public override int GetHashCode()
{
return Tuple.GetHashCode();
}
public Tuple<int, int> Tuple { get; private set; }
}
public void Do()
{
var map = new Dictionary<Key, int>();
map.Add(new Key(1, 2), 3);
map.Add(new Key(1, 2), 4); // will throw System.ArgumentException
}
Another way is just using Tuple
class:
public void Do()
{
var map = new Dictionary<Tuple<int, int>, int>();
map.Add(new Tuple<int, int>(1, 2), 3);
map.Add(new Tuple<int, int>(1, 2), 4); // will throw System.ArgumentException
}