在==运算符覆盖中使用GetHashCode

Car*_*rlo 1 c#

只是想知道我在标题中提到的是一个好习惯.这对我来说很有意义,我们重写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
}
Run Code Online (Sandbox Code Playgroud)

这就是我以前的方式:

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();
}
Run Code Online (Sandbox Code Playgroud)

重要的提示:

在CartesianCoordinates对象中,X是一个int,Y是一个字符串:

public int X { get; set; }
public string Y { get; set; }
Run Code Online (Sandbox Code Playgroud)

Lmk,提前谢谢!

Tho*_*que 8

这样做不仅是不好的做法,也是错的!两个相等的对象必须具有相同的哈希码,但事实恰恰相反:两个不同的对象可以具有相同的哈希码(通常会).因此,如果您使用哈希码来确定对象是否相等,在某些情况下,当它们实际上不同但恰好碰巧具有相同的哈希码时,您会认为它们相等.哈希码不是唯一标识符......

根据您GetHashCode的实现,对象坐标(x, y)(y, x)将被视为相等(因为x + y == y + x)

  • @ Carlo,一个HashSet(以及其他类似哈希表的数据结构)为每个不同的哈希码都有一个不同的"桶".具有相同哈希码的所有项目最终都在同一个存储桶中.当您测试哈希集中项目的存在时,它会根据哈希码找到正确的存储桶,然后在存储桶上执行线性搜索(使用等于)来查找您正在查找的项目.这就是为什么拥有良好的哈希码分布对性能很重要,以避免在同一个桶中有太多项目. (2认同)