Search code examples
c#containersoverloadingequals

How do I overload the Equals operator in my class so that Queue.Contains() works?


I've created a class State. For a Queue of State objects, I want to test whether the Queue already contains a State object of equal value. Two State objects, which each contain a 2D boolean array, are equal when all values of the arrays are equal and in the same order.

Here is my relevant code:

public class State {
   Boolean[,] grid = new Boolean[4,4];

   Public State(Boolean[,] passedGrid){ //Constructor
       grid = Array.Copy(passedGrid, grid, 16);
   }

   public bool Equals(State s2){ //Overloaded equals operator
         for (int x = 0; x < 4; x++){
                 for (int y = 0; y < 4; y++){
                      if (grid[x, y] != s2.grid[x, y]){
                            return false;
                        }
                    }
                }
                return true;
            }

}

    public void testContains(Boolean[] testArray) {
        Queue<State> testQueue = new Queue<State>();
        State s1 = new State(testArray);
        State s2 = new State(testArray);
        testQueue.Enqueue(s1);
        Boolean b = testQueue.Contains(s2);
    }

Unfortunately, when testContains() is called and I check the value of testQueue.Contains(s2) at the end, it still says the test is false, even though they have identical array values and the Equals operator was overloaded to test for that. What do I have to do or change to get Queue.Contains to work with my object? I read somewhere that getHashCode() is recommended to be overloaded whenever Equals is overloaded. Do I need to do that in this case? If so, what should the overloaded getHashCode() do?


Solution

  • To override Equals, you need to use object as the parameter type and the keyword override.

    so you can try something like

        public override bool Equals(object obj)
        {
            return Equals(obj as State);
        }
        public bool Equals(State s2)
        { //Overloaded equals operator 
            for (int x = 0; x < 4; x++)
            {
                for (int y = 0; y < 4; y++)
                {
                    if (grid[x, y] != s2.grid[x, y])
                    {
                        return false;
                    }
                }
            }
            return true;
        }
    

    You should probably also include test for null

    Have a look at How to define value equality for a class or struct (C# Programming Guide)