在.NET GetHashCode方法中,很多地方都使用.NET 方法.特别是在快速查找集合中的项目或确定相等性时.是否有关于如何GetHashCode为我的自定义类实现覆盖的标准算法/最佳实践,因此我不会降低性能?
很久以前,我以1.25美元的价格从交易台上买了一本数据结构书.在其中,哈希函数的解释说,由于"数学的本质",它最终应该由质数修改.
你对1.25美元的书有什么期望?
无论如何,我有多年的时间来思考数学的本质,但仍然无法弄明白.
当存在大量的桶时,数字的分布是否真的更均匀?或者这是一个老程序员的故事,每个人都接受,因为其他人都接受它?
如您所知,GetHashCode返回一个半唯一值,可用于标识集合中的对象实例.作为一种好的做法,建议覆盖此方法并实现自己的方法.
我的问题是 - 在处理自定义对象时是否覆盖此方法?如果是这样,您使用什么算法来生成唯一ID?
我正在考虑生成GUID,然后从该识别器获取整数数据.
好吧,在你因为互联网上发布了数百个类似的声音问题而疯狂之前,我可以向你保证,我刚刚花了几个小时阅读所有这些问题并且没有找到我的问题的答案.
基本上,我的一个大型应用程序遇到了这样的情况:属性Binding上的某些s ListBox.SelectedItem将停止工作,或者在对当前所选项目进行编辑后程序将崩溃.我最初询问'已经添加了相同键的项目'从代码问题中选择ListBoxItem的例外,但没有得到答案.
直到本周,我才有时间解决这个问题.现在简而言之,我找出了问题的原因.这是因为我的数据类型类已经覆盖了Equals方法,因此也覆盖了方法GetHashCode.
现在对于那些不知道这个问题的人,我发现你只能GetHashCode使用不可变字段/属性来实现该方法.使用Harvey Kwok对Overriding GetHashCode()帖子的回答摘录来解释这个:
问题是Dictionary和HashSet集合正在使用GetHashCode将每个项目放在存储桶中.如果基于某些可变字段计算哈希码,并且在将对象放入HashSet或Dictionary后实际更改了字段,则无法再从HashSet或Dictionary中找到该对象.
所以实际问题是因为我在方法中使用了可变属性GetHashCode.当用户在UI中更改这些属性值时,对象的关联哈希码值会发生更改,然后在其集合中无法再找到项目.
所以,我的问题是处理我需要GetHashCode在没有不可变字段的类中实现方法的情况的最佳方法是什么?对不起,让我更加具体,因为该问题已被问过.
Overriding GetHashCode()帖子中的答案表明,在这些情况下,最好只返回一个常量值...一些建议返回值1,而其他建议返回一个素数.就个人而言,我看不出这些建议之间有任何区别,因为我认为只有一个桶用于其中任何一个.
此外,Eric Lippert博客中关于GetHashCode的指南和规则有一个标题为指南的部分:哈希码的分布必须是"随机的",这突出了使用导致使用不足的桶的算法的缺陷.他警告说,算法会减少使用的桶数,并在桶变得非常大时导致性能问题.当然,返回常数属于这一类.
我想到了Guid为我的所有数据类型类(仅在C#中,而不是数据库中)添加一个额外的字段,特别是在GetHashCode方法中使用.所以我想在这个长篇介绍的最后,我的实际问题是哪个实现更好?总结一下:
在没有不可变字段的类中重写Object.GetHashCode()时,最好从GetHashCode方法返回一个常量,还是readonly为每个类创建一个附加字段,仅用于GetHashCode方法?如果我应该添加一个新字段,它应该是什么类型,我不应该将它包含在Equals方法中?
虽然我很高兴收到任何人的答案,但我真的希望得到高级开发人员的答案,他们对这个主题有充分的了解.
gethashcode ×3
algorithm ×2
c# ×2
overriding ×2
.net ×1
class ×1
hash ×1
hashcode ×1
methods ×1
mutable ×1