我一直想知道这个问题,所以我想我会问的。
您将看到的大多数地方都使用相同的语义逻辑来覆盖 Equals 和 GetHashCode 以实现成员平等...但是它们通常使用不同的实现:
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var other = (MyType)obj;
if (other.Prop1 != Prop1)
{
return false;
}
return true;
}
public override int GetHashCode()
{
int hash = -657803396;
num ^= Prop1.GetHashCode();
return num;
}
如果您正在为您的类型实现成员平等(比如说存储在字典中),为什么不直接重写 GetHashCode 然后为 Equals 做这样的事情:
public override bool Equals(object obj)
{
return this.HashEqualsAndIsSameType(obj);
}
public static bool HashEquals(this object source, object obj)
{
if (source != null && obj != null)
{
return source.GetHashCode() == obj.GetHashCode();
}
if (source != null || obj != null)
{
return false;
}
return true;
}
public static bool HashEqualsAndIsSameType<T>(this T source, object obj)
{
return (obj == null || obj.GetType() == typeof(T)) && source.HashEquals(obj);
}
最佳答案
因为存在真正的冲突风险。哈希码不是唯一的。他们可以(当不同时)证明不平等,但永远不能证明平等。寻找元素时:
- 获取哈希码
- 如果哈希码不同,则对象不同;丢弃它
- 如果哈希码相同,检查等于:
- 如果 Equals 报告
true
它们是相同的 - 否则丢弃
考虑 long
... 因为 hash-code 是 int
,很容易看出有很多很多的冲突。
关于c# - GetHashCode 相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3912018/