Search code examples
c#hashsetiequalitycomparer

Checking equality with a HashSet of objects


I am trying to compare two hashsets of Definition type as EqualityComparer<T>.Default.Equals(value, oldValue). Definition is defined as follows

public class Definition
{
    public string Variable { get; set; }
    public HashSet<Location> LocationList { get; set; }

    public override bool Equals(object obj)
    {
        Definition other = obj as Definition;
        return other.Variable.Equals(this.Variable) && other.LocationList!= null &&this.LocationList != null
            && other.LocationList.Count == this.LocationList.Count
            && other.LocationList == this.LocationList;
    }

    public override int GetHashCode()
    {
        return this.Variable.GetHashCode() ^ this.LocationList.Count.GetHashCode();// ^ this.LocationList.GetHashCode();
    }
}

public class Location
{
    public int Line { get; set; }
    public int Column { get; set; }
    public int Position { get; set; }
    public string CodeTab { get; set; }
    public Location(int line, int col, int pos, string tab)
    {
        Line = line;
        Column = col;
        Position = pos;
        CodeTab = tab;
    }
    public override bool Equals(object obj)
    {
        Location other = obj as Location;
        return this.CodeTab == other.CodeTab
            && this.Position == other.Position
            && this.Column == other.Column
            && this.Line == other.Line;
    }
    public override int GetHashCode()
    {
        return this.CodeTab.GetHashCode() ^ this.Position.GetHashCode() 
            ^ this.Column.GetHashCode() ^ this.Line.GetHashCode();
    }
}

Somehow for a similar set, the result is returned as false despite all the information remaining the same. The only difference is that the position of some elements are interchanged, but I know that HashSet won't preserve or check the order while comparing. Can any one advise me on what is going wrong here?

PS: I tried uncommenting this.LocationList.GetHashCode() also, but didn't work.


Solution

  • You need to create a comparer for the sets:

    var setComparer = HashSet<Location>.CreateSetComparer();
    return other.Variable.Equals(this.Variable) && setComparer.Equals(this.LocationList, other.LocationList);