C# 基于GetHashCode的Equals有任何负面后果吗?

C# 基于GetHashCode的Equals有任何负面后果吗?,c#,.net,equals,gethashcode,C#,.net,Equals,Gethashcode,下面的代码可以吗 public override bool Equals(object obj) { if (obj == null || !(obj is LicenseType)) return false; return GetHashCode() == obj.GetHashCode(); } public override int GetHashCode() { return Vendor.GetHashCode() ^ Version.GetH

下面的代码可以吗

public override bool Equals(object obj)
{
  if (obj == null || !(obj is LicenseType))
    return false;
  return GetHashCode() == obj.GetHashCode();
}

public override int GetHashCode()
{
  return
    Vendor.GetHashCode() ^ 
    Version.GetHashCode() ^ 
    Modifiers.GetHashCode() ^ 
    Locale.GetHashCode();
}

所有属性都是枚举/数字字段,并且是定义
LicenseType
对象的唯一属性。

当两个不同的对象返回相同的哈希代码时会发生什么


毕竟,它只是一个散列,因此在对象可以拥有的全部值范围内可能不明显。

当两个不同的对象返回相同的散列码时会发生什么

毕竟,它只是一个散列,因此在对象可以具有的全部值范围内可能不明显。

只有当
GetHashCode
对于每个可能的值都是唯一的时,才可以(没有负面影响)。举一个例子,
short
(一个16位的值)的
GetHashCode
总是唯一的(希望如此:-)),因此将
等于
作为
GetHashCode
的基础是可以的

另一个例子,对于
int
GetHashCode()
是整数的值,因此我们得到了
((int)值)。GetHashCode()==((int)值)
。请注意,例如
short
(但
short
的哈希代码仍然是唯一的,只是它们使用了更复杂的公式)

请注意,Patrick所写的是错误的,因为对于对象/类的“用户”来说是错误的。您是对象/类的“编写者”,因此您定义了相等的概念和哈希代码的概念。如果定义两个对象总是相等的,不管它们的值是什么,那么就可以了

public override int GetHashCode() { return 1; }
public override bool Equals(object obj) { return true; }
平等的唯一重要因素是:

需要实现来确保如果Equals方法为两个对象x和y返回true,那么GetHashCode方法为x返回的值必须等于为y返回的值

Equals方法是自反的、对称的和传递的

显然,您的
Equals()
GetHashCode()
符合此规则,因此它们也可以

出于好奇,等式运算符(
==
)至少有一个例外(通常根据
Equals
方法定义等式运算符)

这是因为IEEE 754标准中将
NaN
值定义为不同于所有值,
NaN
包括。出于实际原因,
Equals
返回
true

只有当
GetHashCode
对于每个可能的值都是唯一的时,才可以(没有负面后果)。举一个例子,
short
(一个16位的值)的
GetHashCode
总是唯一的(希望如此:-)),因此将
等于
作为
GetHashCode
的基础是可以的

另一个例子,对于
int
GetHashCode()
是整数的值,因此我们得到了
((int)值)。GetHashCode()==((int)值)
。请注意,例如
short
(但
short
的哈希代码仍然是唯一的,只是它们使用了更复杂的公式)

请注意,Patrick所写的是错误的,因为对于对象/类的“用户”来说是错误的。您是对象/类的“编写者”,因此您定义了相等的概念和哈希代码的概念。如果定义两个对象总是相等的,不管它们的值是什么,那么就可以了

public override int GetHashCode() { return 1; }
public override bool Equals(object obj) { return true; }
平等的唯一重要因素是:

需要实现来确保如果Equals方法为两个对象x和y返回true,那么GetHashCode方法为x返回的值必须等于为y返回的值

Equals方法是自反的、对称的和传递的

显然,您的
Equals()
GetHashCode()
符合此规则,因此它们也可以

出于好奇,等式运算符(
==
)至少有一个例外(通常根据
Equals
方法定义等式运算符)

这是因为IEEE 754标准中将
NaN
值定义为不同于所有值,
NaN
包括。出于实际原因,
Equals
返回
true

否,非常清楚地说明:

您不应该假设相等的哈希代码意味着对象相等

此外:

两个相等的对象返回相等的哈希代码。但是,情况并非如此:相等哈希代码并不意味着对象相等

以及:

警告:

  • 不要测试散列码是否相等,以确定两个对象是否相等。(不相等的对象可以具有相同的哈希代码。)要测试相等性,请调用或方法
不,声明非常明确:

您不应该假设相等的哈希代码意味着对象相等

此外:

两个相等的对象返回相等的哈希代码。但是,情况并非如此:相等哈希代码并不意味着对象相等

以及:

警告:

  • 不要测试散列码是否相等,以确定两个对象是否相等。(不相等的对象可以具有相同的哈希代码。)要测试相等性,请调用或方法
必须注意的是,如果两个对象具有相同的哈希代码,则它们必须相等,这不是一条规则

大概只有四十亿个可能的散列码,但显然有四十多亿个可能的对象。仅10个字符的字符串就远远超过40亿个。因此,根据鸽子洞原理,必须至少有两个不相等的对象共享相同的哈希代码

假设您有一个Customer对象,它有一系列字段,如Name、Address等。如果在两个不同的进程中创建两个具有完全相同数据的对象,则它们不必返回相同的哈希代码。如果你周二在一个过程中制造了这样一个物体,关闭它,一个