Reputation: 149
I have been trying to make my equality definition work but found out that IEqualityComparer does not seem to work whatsoever.
My class:
public class DBTileSimple
{
public int X;
public int Y;
public int Zoom;
public DBTileSimple(int x, int y, int z)
{
X = x;
Y = y;
Zoom = z;
}
}
Testing IEqualityComparer, so it should be equal for any object:
public class TileComparer : IEqualityComparer<DBTileSimple>
{
public bool Equals(DBTileSimple x, DBTileSimple y)
{
return true;
}
public int GetHashCode(DBTileSimple obj)
{
return 1;
}
}
Result:
DBTileSimple t1 = new DBTileSimple(10, 20, 17);
DBTileSimple t2 = new DBTileSimple(10, 20, 17);
Log.Info("t1 and t2 = " + (t1 == t2));
returns t1 and t2 = false
My ultimate goal is to compare two lists with these objects and do logical operations over them (intersection, etc.).
So for example:
DBTileSimple t1 = new DBTileSimple(10, 20, 17);
DBTileSimple t2 = new DBTileSimple(10, 20, 17);
List<DBTileSimple> list1 = new List<DBTileSimple>();
list1.Add(t1);
List<DBTileSimple> list2 = new List<DBTileSimple>();
list2.Add(t2);
list1 = list1.Except(list2).ToList();
Now list1 should be empty but it is not.
Upvotes: 1
Views: 1137
Reputation: 43886
You don't use the TileComparer
at all. If you want to use it to compare to DBTileSimple
instances you can do it like that:
DBTileSimple t1 = new DBTileSimple(10, 20, 17);
DBTileSimple t2 = new DBTileSimple(10, 20, 17);
TileComparer comparer = new TileComparer();
Log.Info("t1 and t2 = " + comparer.Equals(t1, t2));
If you want t1 == t2
to work, you have to overload that operator:
public class DBTileSimple
{
//...
public static bool operator==(DBTileSimpe t1, DBTileSimpe t2)
{
return true;
}
public static bool operator!=(DBTileSimpe t1, DBTileSimpe t2)
{
return false;
}
}
Note that you need to overload both ==
and !=
, see Microsoft's guidelines.
UPDATE after your edit:
To use your comparer with Except
you simply need to pass an instance of it:
list1 = list1.Except(list2, new TileComparer()).ToList();
Upvotes: 6
Reputation: 755
Overriding the Equals() will have an effect only with
t1.Equals(t2)
To make your code work, you have to add this code in the DBTileSimple class:
public static bool operator ==(DBTileSimple x, DBTileSimple y)
{
return x.propA == y.propB;
}
Please check this link for more information about overriding equality:
https://msdn.microsoft.com/en-US/library/ms173147(v=vs.80).aspx
EDIT:
If you need to do some other logic besides the equality of two DBTileSimple objects, then I think it would be best to create another method that handles this logic. Equality has to remain as a way of comparing the equality of two objects, otherwise it might cause confusion in the future.
Upvotes: 0
Reputation: 6836
You need to implement == operator like this:
public static bool operator ==(DBTileSimple a, DBTileSimple b)
{
// Return true if the fields match:
return a.x == b.x && a.y == b.y && a.Zoom == b.Zoom;
}
public static bool operator !=(DBTileSimple a, DBTileSimple b)
{
return !(a == b);
}
Upvotes: 0