以下代码是否正常?
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
对象的属性。
答案 0 :(得分:6)
当两个不同的对象返回相同的HashCodes时会发生什么?
毕竟,它只是一个哈希值,因此可能与对象可以拥有的整个值范围不同。
答案 1 :(得分:6)
不,the documentation非常清楚地表明:
您不应该假设相等的哈希码意味着对象相等。
此外:
两个相等的对象返回相等的哈希码。但是,反之则不然:相等的哈希码并不意味着对象相等
和
注意:
- 不测试哈希码的相等性以确定两个对象是否相等。 (不相等的对象可以具有相同的哈希码。)要测试相等性,请调用ReferenceEquals或Equals方法。
答案 2 :(得分:1)
只有当GetHashCode
对每个可能的值都是唯一的时,才可以(没有负面后果)。举一个例子,GetHashCode
(16位值)的short
始终是唯一的(让我们希望如此:-)),所以基于Equals
GetHashCode
没问题。
另一个示例,对于int
,GetHashCode()
是整数的值,因此我们有((int)value).GetHashCode() == ((int)value)
。请注意,对于short
而言,这不是真的(但short
的哈希码仍然是唯一的,只是它们使用更复杂的公式)
请注意帕特里克所写的内容是错误的,因为对于"用户而言,这是正确的。一个对象/类。你是"作家"对象/类的定义,因此您定义了相等的概念和哈希码的概念。如果你定义两个对象总是相等的,无论它们的价值如何,那就没关系。
public override int GetHashCode() { return 1; }
public override bool Equals(object obj) { return true; }
Equals唯一重要的rules是:
需要实现以确保如果Equals方法对两个对象x和y返回true,则x的GetHashCode方法返回的值必须等于为y返回的值。
Equals方法具有反身性,对称性和传递性......
显然,您的Equals()
和GetHashCode()
可以使用此规则,因此可以。
出于好奇,等于运算符(==
)至少有一个例外(通常你根据Equals
方法定义相等运算符)
bool v1 = double.NaN.Equals(double.NaN); // true
bool v2 = double.NaN == double.NaN; // false
这是因为{75}标准中定义的NaN
值与所有值不同,NaN
包括。出于实际原因,Equals
会返回true
。
答案 3 :(得分:0)
必须注意的是,如果两个对象具有相同的哈希码,则它们必须相等,这不是一个规则。
只有大约40亿个可能的哈希码,但显然有超过40亿个可能的对象。仅有超过40亿个十字符串。因此,Pigeonhole原则必须至少有两个不相等的对象共享相同的哈希码。
假设您有一个Customer对象,其中包含一系列字段,如Name,Address等。如果在两个不同的进程中使用完全相同的数据生成两个这样的对象,则它们不必返回相同的哈希代码。如果你在星期二的一个进程中创建这样一个对象,关闭它,并在星期三再次运行程序,哈希码可能会有所不同。
这在过去曾经被人咬伤过。 System.String.GetHashCode
的文档特别指出,两个相同的字符串在不同版本的CLR中可以有不同的哈希码,事实上它们也是如此。不要在数据库中存储字符串哈希,并期望它们永远相同,因为它们不会成为。