I have the following class:
public class SimplePolygon
{
Point[] pointCollection;
public SimplePolygon(Point[] pointCollection)
{
this.pointCollection = pointCollection;
}
public override int GetHashCode()
{
if (ReferenceEquals(pointCollection, null) || (pointCollection.Count() == 0))
return pointCollection.GetHashCode();
int hash = 17;
for (int i = 0; i < pointCollection.Count(); i++)
hash = hash * 23 + pointCollection[i].GetHashCode();
return hash;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(obj, null))
return false;
if (!(obj is SimplePolygon))
return false;
if (this.pointCollection.Count() != (obj as SimplePolygon).pointCollection.Count())
return false;
for (int i = 0; i < this.pointCollection.Count(); i++)
if (!(obj as SimplePolygon).pointCollection.Contains(this.pointCollection[i]))
return false;
return true;
}
}
My problem is that Equals method and GetHashCode method are not consistent:
Point p1, p2, p3, p4;
//...create and initialize p1, p2, p3, p4.
SimplePolygon polygon1 = new SimplePolygon(p1, p2, p3, p4);
SimplePolygon polygon2 = new SimplePolygon(p4, p3, p2, p1);
polygon1 == polygon2; //this is true
polygon1.GetHashCode() == polygon2.GetHashCode(); //this is false
And this violates the rule that says that two objects that are equal should have the same hash code.
My problem is that the hash code is generated going from the first element of the array to the last, while the Equals method does not care about the order of Points in the array(for simple polygons or non intersecting polygons, the order of points is irelevant – (p1, p2, p3, p4) is the same as (p2, p3, p4, p1) or (p3, p4, p1, p2) or (p4, p3, p2, p1))
Does anyone know a good method for generating hash codes for such situations?
Change
e.g. to
so it doesn’t depend on the order of the points.