C# GetHashCode是否应取决于类型?
首先,我使用所描述的C# GetHashCode是否应取决于类型?,c#,inheritance,gethashcode,C#,Inheritance,Gethashcode,首先,我使用所描述的GetHashCode算法。现在,想象以下(人为的)例子: class Foo { public Foo(int intValue, double doubleValue) { this.IntValue = intValue; this.DoubleValue = doubleValue; } public int IntValue { get; private set; } public doubl
GetHashCode
算法。现在,想象以下(人为的)例子:
class Foo
{
public Foo(int intValue, double doubleValue)
{
this.IntValue = intValue;
this.DoubleValue = doubleValue;
}
public int IntValue { get; private set; }
public double DoubleValue { get; private set; }
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + IntValue.GetHashCode();
hash = hash * 23 + DoubleValue.GetHashCode();
return hash;
}
}
}
class DerivedFoo : Foo
{
public DerivedFoo(int intValue, double doubleValue)
: base(intValue, doubleValue)
{
}
}
如果我有一个Foo
和一个DerivedFoo
对于每个属性都有相同的值,那么它们将有相同的哈希代码。这意味着我可以使用HashSet
或在Linq中使用Distinct
方法,这两个实例将被视为相同
我可能只是误解了GetHashCode
的用法,但我希望这两个实例具有不同的哈希代码。这是一个无效的期望值还是应该GetHashCode
在计算中使用该类型?(或者DerivedClass
是否也应该覆盖GetHashCode
)
顺便说一句,我意识到与这个主题相关的问题很多,但我还没有发现一个问题可以直接回答这个问题。GetHashCode()
不应该保证唯一性(尽管如果尽可能唯一,它有助于提高性能)
GetHashCode()
的主要规则是等价对象必须具有相同的哈希代码,但这并不意味着非等价对象不能具有相同的哈希代码
如果两个对象具有相同的哈希代码,则调用Equals()
方法查看它们是否相同。由于类型不同(当然,这取决于您如何编写Equals重载),它们将不相等,因此也可以
即使每种类型有不同的散列码算法,也总是有冲突的可能,因此也需要进行Equals()
检查
现在给出上面的示例,您没有实现Equals()
这将使每个对象都不同,而不管哈希代码是什么,因为object
中Equals()
的默认实现是一个引用相等检查
如果没有,请继续为每个类型重写Equals()
(如果愿意,它们可以继承GetHashCode()
的实现,或者有新的实现),并且在声明它们相等之前,可以确保compare-to对象的类型相同。并确保始终实现Equals()
和GetHashCode()
,以便:
的对象必须具有相同的Equals()
结果GetHashCode()
- 具有不同
的对象必须不是GetHashCode()
Equals()