IEqualityComparer在通用字典上

本文关键字:字典 TKey IEqualityComparer | 更新日期: 2023-09-27 17:54:43

今天在研究一个项目时,我正在查看Dictionary<TKey, TValue>的文档。在这里,我发现了一些我过去可能忽略的注释:

因为键可以被继承并且它们的行为可以被改变,所以它们的绝对唯一性不能通过使用Equals方法进行比较来保证。

同样的评论似乎在我之后看到的大多数(键控)集合类的文档中到处都是。但是我找不到任何例子来说明所描述的潜在问题,尽管我很确定这就是接受IEqualityComparer<TKey>的构造函数的目的,并且当复杂类型被用作键时,它会出现。

谁能给我解释一下在什么情况下可能会遇到这个评论所指向的问题?只要我不确切地知道这样的问题是如何或何时出现的,我就不能在设计中考虑到它。

IEqualityComparer<TKey>在通用字典上

使用任何对象/值作为键并不像听起来那么简单,因为它取决于Equals和GetHashCode的正确实现。说实话,"子类扭曲事物"的场景并不是我经常遇到的,然而,这个API的一个更常见的用途是允许使用当你使用的类型作为键不提供合适的Equals/GetHashCode,并且不在你的控制范围内。例如,您想使用Customer作为键,但您只想匹配Id(即,您不想要默认的引用相等行为;也许你正在处理来自不同来源的不同对象,并且需要根据Id将不同的实例视为相等。在这种情况下,您可以编写一个自定义的相等比较器,它只考虑Id

个人;我喜欢简单。I 很少(如果有的话)索引除int, string等之外的任何对象。这使事情变得简单—同时显示了另一种常见场景:为string键提供区分大小写/不敏感或区分区域性/不敏感的比较器。

假设你正在服务器上处理一个大的查询结果:你正在构建一个大的Dictionary<Student, List<Result>>…与此同时,另一个人将的标识更改为位于你下面的共享模型中的Student对象(比如有人将"Bob"的名字更改为"Fred")。如果Name属性对Students的Equals(和HashCode)方法有贡献,那么下次您尝试向Dictionary中添加"Bob"的Result时,您将无法在Dictionary中找到代表Bob的对象,这仅仅是因为"Bob"对象的HashCode发生了变化……因此,他现有的结果是"丢失"的。

使用任何类作为键的技巧之一是使它的标识字段(在equals和HashCode方法中使用的字段)不可变。在实践中,这并不重要,直到你从多个线程并发访问你的模型。在单线程环境中,你真的不必担心,因为你不会傻到在你需要的时候改变一个你需要的Identity。

明白了吗?

欢呼。基斯。