如何在课堂上没有一成不变的领域重写Object.GetHashCode()的时候回来? [英] What to return when overriding Object.GetHashCode() in classes with no immutable fields?

查看:148
本文介绍了如何在课堂上没有一成不变的领域重写Object.GetHashCode()的时候回来?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,你得到所有疯了,因为有数以百计的发音相似的问题在互联网上发布之前,我可以向你保证,我刚刚花了几个小时阅读的所有的和没有。找到了答案,我的问题。

Ok, before you get all mad because there are hundreds of similar sounding questions posted on the internet, I can assure you that I have just spent the last few hours reading all of them and have not found the answer to my question.

基本上,我的大面积推广应用一人被痛苦从情况下一些绑定 S置于 ListBox.SelectedItem 属性将停止工作或程序的编辑后会崩溃已作出的当前选择的项目。我最初问的具有相同键的项已被添加异常从代码中选择一个ListBoxItem的问题在这里,但没有得到回应。

Basically, one of my large scale applications had been suffering from a situation where some Bindings on the ListBox.SelectedItem property would stop working or the program would crash after an edit had been made to the currently selected item. I initially asked the 'An item with the same key has already been added' Exception on selecting a ListBoxItem from code question here, but got no answers.

我就没'T有时间解决这一问题,直到这个星期,当我得到了许多天来梳理出来。现在削减长话短说,我发现了该问题的原因。这是因为我的数据类型类已覆盖了等于方法,因此的GetHashCode 方法为好。

I hadn't had time to address that problem until this week, when I was given a number of days to sort it out. Now to cut a long story short, I found out the reason for the problem. It was because my data type classes had overridden the Equals method and therefore the GetHashCode method as well.

现在对于那些你不知道这个问题,我发现,你只能实施的GetHashCode 方法使用的一成不变的字段/属性。利用哈维郭的回答一个摘录href=\"http://stackoverflow.com/questions/11481323/overriding-gethashcode\">重写GetHashCode()方法发帖解释这个

Now for those of you that are unaware of this issue, I discovered that you can only implement the GetHashCode method using immutable fields/properties. Using a excerpt from Harvey Kwok's answer to the Overriding GetHashCode() post to explain this:

的问题是,正在使用的字典和HashSet的集合的GetHashCode每个项目放置在水桶。对象被放置到HashSet的或字典之后根据某些可变字段如果哈希码计算并字段被真正改变,对象不再能够从HashSet的或字典中找到。

The problem is that GetHashCode is being used by Dictionary and HashSet collections to place each item in a bucket. If hashcode is calculated based on some mutable fields and the fields are really changed after the object is placed into the HashSet or Dictionary, the object can no longer be found from the HashSet or Dictionary.

所以的实际的问题造成的,因为我已经使用的可变的在的GetHashCode 方法。当用户在UI改变这些属性值,对象的相关联的散列码值,然后再项可能不再在其收藏中找到

So the actual problem was caused because I had used mutable properties in the GetHashCode methods. When users changed these property values in the UI, the associated hash code values of the objects changed and then items could no longer be found in their collections.

所以,我的问题是什么是我需要的地方实现类的GetHashCode 法的办理情况的最好办法没有一成不变的领域?对不起,让我更加具体,为的的问题的的被问过。

So, my question is what is the best way of handling the situation where I need to implement the GetHashCode method in classes with no immutable fields? Sorry, let me be more specific, as that question has been asked before.

在答案< A HREF =htt​​p://stackoverflow.com/questions/11481323/overriding-gethashcode>重写GetHashCode()方法后建议,在这种情况下,最好是只返回一个恒定值...有人建议返回值 1 ,而其他建议返回一个素数。就个人而言,我看不出这些建议有什么区别,因为我本来以为只会有用于任何其中一个桶。

The answers in the Overriding GetHashCode() post suggest that in these situations, it is better to simply return a constant value... some suggest to return the value 1, while other suggest returning a prime number. Personally, I can't see any difference between these suggestions because I would have thought that there would only be one bucket used for either of them.

此外,<一个HREF =htt​​p://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/相对=nofollow>准则和GetHashCode的在埃里克利珀的博客文章规则有部分标题为指南:散列码的分布必须是随机使用的其中突出使用了一种算法,导致没有足够的桶的陷阱。他警告那的算法减少使用的桶数,并导致性能问题当铲斗变得非常大的。当然,返回一个常数就属于这一类。

Furthermore, the Guidelines and rules for GetHashCode article in Eric Lippert's Blog has a section titled Guideline: the distribution of hash codes must be "random" which highlights the pitfalls of using an algorithm that results in not enough buckets being used. He warns of algorithms that decrease the number of buckets used and cause a performance problem when the bucket gets really big. Surely, returning a constant falls into this category.

我不得不添加额外的的Guid 字段所有的想法我的数据类型的类(只是在C#中,而不是数据库)特别是在且仅在的GetHashCode 方法使用。所以我想在这个漫长前奏结束后,我的实际的问题是,它的实现是更好吗?总结:

I had an idea of adding an extra Guid field to all of my data type classes (just in C#, not the database) specifically to be used in and only in the GetHashCode method. So I suppose at the end of this long intro, my actual question is which implementation is better? To summarise:

当在没有一成不变的领域类重写Object.GetHashCode(),是它更好地返回从的GetHashCode 方法的常量,或者为每个类创建一个额外的只读字段,只是为了在的GetHashCode 方法一起使用?如果我要补充一个新的领域,它应该是什么类型,我不应该那么它包含在等于方法?

When overriding Object.GetHashCode() in classes with no immutable fields, is it better to return a constant from the GetHashCode method, or to create an additional readonly field for each class, solely to be used in the GetHashCode method? If I should add a new field, what type should it be and shouldn't I then include it in the Equals method?

虽然我很高兴地收到任何答案,我真的很希望能够接收来自高级开发人员的回答与此主题相关的可靠的知识。

While I am happy to receive answers from anyone, I am really hoping to receive answers from advanced developers with a sound knowledge on this subject.

推荐答案

回到基础。你读我的文章;看了一遍。那些有关你的情况这两个铁定的规则是:

Go back to basics. You read my article; read it again. The two ironclad rules that are relevant to your situation are:


  • 年。等价的:如果x的哈希码不等于y的哈希码,则x和y必须是不平等

  • x的散列码必须在x是一个哈希表保持稳定。

这些都是对的正确的要求。如果不能保证这两个简单的事情,那么你的程序将是不正确的。

Those are requirements for correctness. If you can't guarantee those two simple things then your program will not be correct.

您提出两种解决方案。

You propose two solutions.

您第一个解决方案是,你总是返回一个常数。这符合这两个规则的要求,但你被降低到线性搜索在哈希表。你还不如用一个列表。

Your first solution is that you always return a constant. That meets the requirement of both rules, but you are then reduced to linear searches in your hash table. You might as well use a list.

您提出其他的解决办法是以某种方式产生一个哈希代码为每个对象并将其存储在该对象。这是完全合法的前提是平等的项目具有相同的散列码。如果你这样做,那么你受到限制,因此x等于Ÿ的必须的如果散列码不同,是假的。这似乎让值相等基本上是不可能的。既然你不会是压倒一切等于摆在首位,如果你想引用相等,这似乎是一个非常糟糕的主意,但它的法律的规定,等于是一致的。

The other solution you propose is to somehow produce a hash code for each object and store it in the object. That is perfectly legal provided that equal items have equal hash codes. If you do that then you are restricted such that x equals y must be false if the hash codes differ. This seems to make value equality basically impossible. Since you wouldn't be overriding Equals in the first place if you wanted reference equality, this seems like a really bad idea, but it is legal provided that equals is consistent.

我提出第三种解决方案,那就是:永远不要把你的对象在哈希表中,因为一个哈希表是摆在首位的错误的数据结构。哈希表的一点是要快速回答是这套一成不变值这个给定值?和你没有一套一成不变的值的,所以不要使用哈希表。用于工作的工具。 。使用列表,并做线性搜索的痛苦生活。

I propose a third solution, which is: never put your object in a hash table, because a hash table is the wrong data structure in the first place. The point of a hash table is to quickly answer the question "is this given value in this set of immutable values?" and you don't have a set of immutable values, so don't use a hash table. Use the right tool for the job. Use a list, and live with the pain of doing linear searches.

第四个解决办法是:对用于平等可变域哈希,所有的哈希表中删除对象它是在你发生变异,它只是每一次之前,把它放回之后。这既符合要求:哈希码同意平等,并在哈希表对象的哈希值是稳定的,你仍然可以快速查找

A fourth solution is: hash on the mutable fields used for equality, remove the object from all hash tables it is in just before every time you mutate it, and put it back in afterwards. This meets both requirements: the hash code agrees with equality, and hashes of objects in hash tables are stable, and you still get fast lookups.

这篇关于如何在课堂上没有一成不变的领域重写Object.GetHashCode()的时候回来?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆