相关疑难解决方法(0)

覆盖可变对象的GetHashCode?

我已经阅读了关于何时以及如何覆盖的10个不同的问题,GetHashCode但仍然有一些我不太了解的问题.大多数实现GetHashCode都是基于对象字段的哈希码,但是引用的是值的值GetHashCode永远不会在对象的生命周期内发生变化.如果它所基于的字段是可变的,那该怎么办?另外,如果我确实希望字典查找等基于引用相等而不是我的重写Equals

我主要是Equals为了方便单元测试我的序列化代码,我假设序列化和反序列化(在我的情况下为XML)会导致引用相等,所以我想确保至少它的值是正确的.Equals在这种情况下,这种不良做法是否会被覆盖?基本上在大多数执行代码中,我希望引用相等,而且我总是使用,==而不是重写.我应该创建一个新的方法ValueEquals或什么而不是覆盖Equals?我曾经认为框架总是使用==而不是Equals比较事物,因此我认为覆盖是安全的,Equals因为在我看来,如果你想要有与==运算符不同的第二个等式定义,那么它的目的是什么.从阅读其他几个问题虽然看起来并非如此.

编辑:

看来我的意图不清楚,我的意思是99%的时候我想要普通的老参考平等,默认行为,没有惊喜.对于非常罕见的情况,我希望值相等,并且我希望通过使用.Equals而不是显式请求值相等==.

当我这样做时,编译器建议我也覆盖GetHashCode,这就是这个问题的出现方式.GetHashCode当应用于可变对象时,似乎存在矛盾的目标,即:

  1. 如果a.Equals(b)那时a.GetHashCode()应该== b.GetHashCode().
  2. a.GetHashCode()永远不应该改变的价值a.

当一个可变对象时,这些看起来自然是矛盾的,因为如果对象的状态发生变化,我们期望值的.Equals()变化,这意味着GetHashCode应该改变以匹配变化.Equals(),但GetHashCode不应该改变.

为什么会出现这种矛盾呢?这些建议不适用于可变对象吗?可能是假设,但可能值得一提的是我指的是不是结构的类.

解析度:

我将JaredPar标记为已被接受,但主要用于评论互动.总结我从中学到的是,在边缘情况下实现所有目标和避免可能的古怪行为的唯一方法是仅覆盖EqualsGetHashCode基于不可变字段或实现IEquatable.这种类似似乎削弱了覆盖Equals引用类型的有用性,因为从我看到的大多数引用类型通常没有不可变字段,除非它们存储在关系数据库中以使用它们的主键来标识它们.

.net c# overriding equals gethashcode

57
推荐指数
3
解决办法
8494
查看次数

是否有完整的IEquatable实现引用?

我在这里提出的许多问题涉及IEquatable的实现.我发现正确实现起来非常困难,因为在天真的实现中存在许多隐藏的错误,我发现的关于它的文章非常不完整.我想找到或写出一个必须包括的权威参考:

  • 如何正确实现IEquatable
  • 如何正确覆盖Equals
  • 如何正确覆盖GetHashCode
  • 如何正确实现ToString方法
  • 如何正确实现operator ==
  • 如何实现运算符!=正确

这样一个完整的参考已经存在?

PS:即使是MSDN引用对我来说也是有缺陷的

.net c# equals iequatable gethashcode

46
推荐指数
3
解决办法
2万
查看次数

关于如何正确覆盖object.GetHashCode()的一般建议和指南

根据MSDN,散列函数必须具有以下属性:

  1. 如果两个对象比较相等,则每个对象的GetHashCode方法必须返回相同的值.但是,如果两个对象的比较不相等,则两个对象的GetHashCode方法不必返回不同的值.

  2. 只要没有对对象状态的修改来确定对象的Equals方法的返回值,对象的GetHashCode方法必须始终返回相同的哈希代码.请注意,这仅适用于当前应用程序的执行,并且如果再次运行应用程序,则可以返回不同的哈希代码.

  3. 为获得最佳性能,哈希函数必须为所有输入生成随机分布.


我一直在以下场景中找到自己:我创建了一个类,实现IEquatable<T>并重写了object.Equals(object).MSDN声明:

重写Equals的类型也必须覆盖GetHashCode; 否则,Hashtable可能无法正常工作.

然后它通常会为我停止一点.因为,你如何正确覆盖object.GetHashCode()?从来没有真正知道从哪里开始,这似乎是很多陷阱.

在StackOverflow中,有很多与GetHashCode重写相关的问题,但大多数问题似乎都是针对非常特殊的情况和具体问题.因此,我想在这里得到一个很好的汇编.概述与一般建议和指南.该做什么,不该做什么,常见的陷阱,从哪里开始,等等.

我希望它特别针对C#,但我认为它对其他.NET语言也有同样的作用(?).


我想也许最好的方法是每个主题创建一个答案,首先是快速简短的答案(如果可能的话,尽可能接近单行),然后可能会有更多信息,并以相关问题,讨论,博客文章等结束. ,如果有的话.然后,我可以创建一个帖子作为接受的答案(将其置于顶部),只需一个"目录".尽量保持简洁明了.而且不要只链接到其他问题和博客文章.尝试采用它们的本质,然后链接到源(特别是因为源可能会消失.另外,请尝试编辑和改进答案,而不是创建许多非常相似的答案.

我不是一个非常优秀的技术作家,但我至少会尝试格式化答案,使它们看起来很相似,创建目录等.我也会尝试在这里搜索一些相关的问题来回答部分问题.这些并且可能拉出我能管理的那些的本质.但由于我在这个主题上不是很稳定,所以我会尽量远离这个主题:p

.net c# hashcode gethashcode

44
推荐指数
2
解决办法
6427
查看次数

标签 统计

.net ×3

c# ×3

gethashcode ×3

equals ×2

hashcode ×1

iequatable ×1

overriding ×1