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等。如果在两个不同的进程中创建两个具有完全相同数据的对象,则它们不必返回相同的哈希代码。如果你周二在一个过程中制造了这样一个物体,关闭它,一个