Michal Krča
Michal Krča

Reputation: 149

IEqualityComparer not working at all

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

Answers (3)

Ren&#233; Vogt
Ren&#233; Vogt

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

Kristianne Nerona
Kristianne Nerona

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

Jalal
Jalal

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

Related Questions