我已将Dictionary(TKey,TValue)用于多种用途.但我没有遇到任何实现GetHashCode()的场景,我认为这是因为我的键是主要类型,如int和string.我很想知道场景(真实世界的例子),当一个人应该使用自定义对象的键,从而实现方法GetHashCode()Equals()等.
并且,使用自定义对象的密钥是否需要实现这些功能?
jas*_*son 13
You should override Equals and GetHashCode whenever the default Object.Equals (tests for reference equality) will not suffice. This happens, for example, when the type of your key is a custom type and you want two keys to be considered equal even in cases when they are not the same instance of the custom type.
For example, if your key is as simple as
class Point {
public int X { get; set; }
public int Y { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
and you want two Points two be considered equal if their Xs are equal and their Ys are equal then you will need to override Equals and GetHashCode.
The*_*man 12
只是为了说清楚:有一个重要的事情是:Dictionary<TKey, TValue>和GetHashCode()Dictionary使用GetHashCode来确定两个键是否相等,即如果<TKey>是自定义类型,你应该小心实现GetHashCode().正如Andrew Hare指出这很容易,如果你有一个简单的类型,可以明确地识别你的自定义对象.如果你有一个组合标识符,它会变得有点复杂.
例如,考虑一个复数TKey.复数由它的真实及其虚部决定.两者都是简单的类型,例如double.但是你如何确定两个复数是否相等?您实现GetHashode()自定义复杂类型并组合两个识别部分.
你会在这里找到关于后者的进一步阅读.
UPDATE
根据Ergwun的评论,我检查了Dictionary<TKey, TValue>.Add特别尊重和TKey实施的行为.我必须承认我对结果感到相当惊讶.Equals(object)GetHashCode()
鉴于两个对象k1和k2类型TKey,任意两个对象v1和v2类型TValue,以及一个空的字典d式的Dictionary<TKey, TValue>,这是添加时会发生什么情况v1与主要k1以d第一和v2与关键k2秒(取决于执行TKey.Equals(object)和TKey.GetHashCode()):
k1.Equals(k2) k1.GetHashCode() == k2.GetHashCode() d.Add(k2, v2)
false false ok
false true ok
true false ok
true true System.ArgumentException
Run Code Online (Sandbox Code Playgroud)
结论:我错了,因为我最初认为第二种情况(Equals返回,false但两个关键对象具有相同的哈希码)会引发一个ArgumentException.但正如第三个案例以某种方式显示字典确实使用GetHashCode().无论如何,两个相同类型且相同的对象必须返回相同的哈希码以确保实例Dictionary<TKey, TValue>正常工作,这似乎是一个好建议.