我们什么时候为Dictionary做GetHashCode()?
我已将Dictionary(TKey,TValue)用于多种用途。 但我没有遇到任何实现GetHashCode()的场景,我认为这是因为我的键是主要类型,如int和string。 我很想知道场景(真实世界的例子),当一个人应该使用自定义对象的键,从而实现方法GetHashCode()Equals()等。
并且,使用自定义对象作为密钥是否需要实现这些function?
每当默认的Object.Equals
(测试参考相等)不够时,您应该重写Equals
和GetHashCode
。 例如,当您的密钥类型是自定义类型并且您希望两个密钥被视为相等时,即使在它们不是自定义类型的同一实例的情况下,也会发生这种情况。
例如,如果您的密钥非常简单
class Point { public int X { get; set; } public int Y { get; set; } }
并且如果它们的X
s相等并且它们的Y
s相等则你想要两个Point
s 2被认为是相等的那么你将需要重写Equals
和GetHashCode
。
只是为了说清楚: Dictionary
和GetHashCode()
有一个重要的事情:Dictionary使用GetHashCode来确定两个键是否相等,即如果
是自定义类型,你应该关心实现GetHashCode()
小心。 正如Andrew Hare指出这很容易,如果你有一个简单的类型,可以明确地识别你的自定义对象。 如果你有一个组合标识符,它会变得有点复杂。
例如,将复数视为TKey
。 复数由它的真实及其虚部决定。 两者都是简单类型,例如double
。 但是,如果两个复数相等,你会如何确定? 您为自定义复杂类型实现GetHashode()
并组合两个标识部分。
你会在这里找到关于后者的进一步阅读。
UPDATE
基于Ergwun的评论,我检查了Dictionary
的行为,特别关注TKey
的Equals(object)
和GetHashCode()
。 我必须承认我对结果感到非常惊讶。
给定TKey
类型的两个对象k1
和k2
, TValue
类型的两个任意对象v1
和v2
,以及Dictionary
类型的空字典d
,这是将v1
与键k1
首先添加到d
时发生的情况和v2
与key 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
结论:我错了,因为我最初认为第二种情况(其中Equals
返回false
但两个关键对象具有相同的哈希代码)会引发ArgumentException
。 但是,由于第三种情况以某种方式显示字典确实使用GetHashCode()
。 无论如何,两个相同类型且相同的对象必须返回相同的哈希码以确保实例Dictionary
正常工作似乎是一个好建议。
一个例子是当你需要创建一个复合键(这是一个由多个数据组成的键)。 该组合键将是需要覆盖这些方法的自定义类型。
例如,假设您有一个内存中的地址记录缓存,并且您想检查地址是否在缓存中以节省昂贵的数据库访问以检索它。 我们还要说地址在街道1和邮政编码字段方面是独一无二的。 您可以使用以下内容实现缓存:
class AddressCacheKey { public String StreetOne { get; set; } public String ZipCode { get; set; } // overrides for Equals and GetHashCode }
和
static Dictionary cache;
由于您的AddressCacheKey
类型会覆盖Equals
和GetHashCode
方法,因此它们可以很好地替换字典中的键,您可以确定是否需要访问数据库以检索基于多个的记录一块数据。
你有两个问题。
- 什么时候需要实现GetHashCode()
- 你会用一个对象作为字典键吗?
让我们从1.开始。如果你正在编写一个可能被其他人使用的类,你将需要定义GetHashCode()和Equals(),当引用Equals()不够时。 如果您不打算在字典中使用它,并且它是为了您自己的用法,那么我认为没有理由跳过GetHashCode()等。
对于2),您应该在需要从对象到其他类型的常量时间查找时使用对象。 由于GetHashCode()返回一个数值,并且集合存储引用,因此在Int或字符串上使用Object没有任何代价(请记住字符串是一个对象)。
上述就是C#学习教程:我们什么时候为Dictionary做GetHashCode()?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/984024.html