只是想知道我在标题中提到的是一个好习惯。这对我来说很有意义,我们重写GetHashCode以返回一个基于两个属性的值,如果匹配,则应将两个对象视为相等。逻辑似乎很好,代码可以工作,但我不知道它是否会导致其他问题。
这是使用GetHashCode:
public static bool operator ==(CartesianCoordinates a, CartesianCoordinates b)
{
return a.GetHashCode() == b.GetHashCode(); // Using GetHashCode here
}
public static bool operator !=(CartesianCoordinates a, CartesianCoordinates b)
{
return !(a == b);
}
public override bool Equals(object obj)
{
return this == (CartesianCoordinates)obj; // This just uses the == override
}
public override int GetHashCode()
{
return (this.X + this.Y.ToLower()).GetHashCode(); // GetHashCode hashes the two properties we care about
}
这就是我以前的方式:
public static bool operator ==(CartesianCoordinates a, CartesianCoordinates b)
{
return a.X == b.X && string.Equals(a.Y, b.Y, StringComparison.CurrentCultureIgnoreCase); // The difference is here
}
public static bool operator !=(CartesianCoordinates a, CartesianCoordinates b)
{
return !(a == b);
}
public override bool Equals(object obj)
{
return this == (CartesianCoordinates)obj;
}
public override int GetHashCode()
{
return (this.X + this.Y.ToLower()).GetHashCode();
}
重要提示:
在CartesianCoordinates对象中,X是一个int,Y是一个字符串:
public int X { get; set; }
public string Y { get; set; }
Lmk,提前谢谢!
答案 0 :(得分:8)
这样做不仅是不好的做法,只是错误!两个相等的对象必须具有相同的哈希码,但情况恰恰相反:两个不同的对象可以具有相同的哈希码(通常会)。因此,如果您使用哈希码来确定对象是否相等,在某些情况下,当它们实际上不同但恰好碰巧具有相同的哈希码时,您会认为它们相等。哈希码是不唯一标识符...
根据您的GetHashCode
实施情况,坐标为(x, y)
和(y, x)
的对象将被视为相等(自x + y == y + x
起)
答案 1 :(得分:4)
这是非常错误的
GetHashCode()
不是唯一的。
您的特定示例更糟糕,因为您的GetHashCode()
是可交换的。
答案 2 :(得分:3)
GetHashCode()
可以为两个不相等的CartesianCoordinates
返回相同的值,例如对于两个对象c1
和c2
,c1.x == c2.y
和c1.y == c2.x
。
对于更复杂的对象,如果hashCode是预先计算的,它可以用于短路,但最终你需要比较所有字段。这里的比较是微不足道的
答案 3 :(得分:0)
您的GetHashCode将返回{3,1}和{1,3}的相同值。我怀疑这不是故意的。
如果你的GetHashCode方法返回了更好的哈希码,我仍然建议不要使用GetHashCode作为相等比较。 GetHashCode合约表示具有相同跟踪属性的两个对象应该生成相同的哈希码,而不是具有相同哈希码的两个对象将是相等的。
编辑添加:
有关更好的实施情况的详细信息,请参阅此问题,尤其是Josh Bloch / Jon Skeet的回答。
答案 4 :(得分:0)
不,使用哈希码定义相等是不好的做法(甚至是正确的),因为不同的对象可能具有相同的哈希码(并且在String.GetHashCode的情况下肯定会发生)。
在您的特定情况下,还应注意您的GetHashCode方法甚至不匹配您的Equals
方法,因为除{case}之外,GetHashCode
将返回相同字符串的不同哈希码,而在这种情况下,您的Equals
将返回true。
答案 5 :(得分:0)
您的GetHashCode()
会为(2,4)
和(4,2)
提供相同的结果。可能不是你想要的。
GetHashCode()
通常也不是衡量平等的好方法。即使是非常好的哈希也只是一个32位整数。使用它来测试笛卡尔平面中的相等性将导致许多(无限数量)碰撞。