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.
You need to create a comparer for the sets:
EqualityComparer<T>.Default
will look for an object implementingIEquatable<T>
. Otherwise, it will defer to anObjectEqualityComparer
, which simply checks for reference equality. This is why you're seeing false when references are compared.What you actually want to do is explicitly implement
IEquatable<Location>
. Note you should really make your properties immutable for this to work properly:Now if you look at the type
EqualityComparer
created byDefault
, you'll seeGenericEqualityComparer<Location>
: