Search code examples
c#templatesgenericsequals

C# Using Equals method in a generic list fails


I have a project where I have class State which uses templates. I have a class Cell, and I use it as State, so State holds a Cell as genericState. Now I have a generic function which checks if two instances are equal. Problem is, it never leaves the State Equals method to Cell Equals method.

public class State<T>
{
    public T genericState;  //in my case T is a cell
    public State(T cellState) // CTOR
    {
        this.genericState = cellState;  
    }

    public override bool Equals(object obj)
    {            
        return genericState.Equals((obj as State<T>).genericState); 
    } //never leaves
}

and code of Class Cell, in which it never gets:

public class Cell
{
    public int row, col;
    public bool visited;
    public char value;
    public bool Equals(Cell other)   //never gets here
    {            
       return other != null && other.row == row && other.col == col;    
    }
 }

I don't understand why it never gets to Equal method of Cell. What could be wrong with the code?


Solution

  • The problem is that your code does not know that T has a special method

    bool Equals<T>(T other)
    

    It thinks that it should be calling Cell's override of Equals(object), which your code does not override.

    Fixing this is simple: add IEquatable<Cell> to the list of interfaces implemented by Cell, and add a constraint on T to ensure that it implements IEquatable<T>:

    public class State<T> where T : IEquatable<T> {
        ... // The rest of the code remains the same
    }
    ...
    public class Cell : IEquatable<Cell> {
        ... // The rest of the code remains the same
    }