Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dictionary with Tuple as Key GetHashCode is not called

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 Keyclass 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?

like image 518
A-Sharabiani Avatar asked Jun 07 '26 04:06

A-Sharabiani


1 Answers

Another approach is to use ValueTuple as a key, which will be compared by it's values by default.

public static void Main() 
{
    var map = new Dictionary<(int, int), int>();

    map.Add((1, 2), 3);
    map.Add((1, 2), 4); // Throw an exception
}

If you like to have own class to represent a key you can simply create subclass of Tuple<int, int> and get required behaviour "for free"

public class Key : Tuple<int, int>
{
    public Key(int item1, int item2) : base(item1, item2)
    {
    }
}
like image 92
Fabio Avatar answered Jun 10 '26 09:06

Fabio