简体   繁体   English

IEqualityComparer根本不起作用

[英]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. 我一直在尝试使我的相等性定义起作用,但发现IEqualityComparer似乎不起作用。

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: 测试IEqualityComparer,因此对于任何对象它都应相等:

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 返回t1和t2 =

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. 现在list1应该为空,但不是。

You don't use the TileComparer at all. 您根本不需要使用 TileComparer If you want to use it to compare to DBTileSimple instances you can do it like that: 如果要使用它与DBTileSimple实例进行比较,可以这样做:

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: 如果要让t1 == t2起作用,则必须重载该运算符:

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 . 请注意,您需要重载==!= ,请参阅Microsoft准则


UPDATE after your edit: 编辑后更新:

To use your comparer with Except you simply need to pass an instance of it: 要将比较器与Except一起使用,您只需要传递一个实例:

list1 = list1.Except(list2, new TileComparer()).ToList();

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);
}

Overriding the Equals() will have an effect only with 覆盖Equals()仅对

t1.Equals(t2)

To make your code work, you have to add this code in the DBTileSimple class: 为了使您的代码正常工作,您必须在DBTileSimple类中添加以下代码:

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 https://msdn.microsoft.com/zh-CN/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. 如果除了两个DBTileSimple对象的相等性之外还需要执行其他逻辑,那么我认为最好创建另一个处理该逻辑的方法。 Equality has to remain as a way of comparing the equality of two objects, otherwise it might cause confusion in the future. 必须保留相等性,作为比较两个对象相等性的一种方式,否则将来可能会引起混乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM