Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-readonly fields referenced in GetHashCode()

Tags:

c#

.net

.net-4.0

Started with overriding concepts and I override the methods Equals and GetHashCode.

Primarily I came up with this "very simple code":

internal class Person     {         public string name;          public int age;          public string lname;          public Person(string name, int age, string lname)         {             this.name = name;             this.age = age;             this.lname = lname;         }          public override bool Equals(object obj)         {             var person = obj as Person;             if (person != null)             {                 return person.age == this.age && person.name == this.name && person.lname == this.lname;             }              return false;         }          public override int GetHashCode()         {             return this.age.GetHashCode() * this.name.GetHashCode() * this.lname.GetHashCode();         }     } 

While this works great, my "co-developer" Mr.Resharper gave me some suggestions:

  1. Non-readonly fields referenced in GetHashCode(). Suggestions came in this line of code:

return this.age.GetHashCode() * this.name.GetHashCode() * this.lname.GetHashCode();

  1. Should we use GetHashCode only for Properties?
like image 513
now he who must not be named. Avatar asked Dec 16 '13 05:12

now he who must not be named.


People also ask

Should I override GetHashCode?

Why is it important to override GetHashCode ? It s important to implement both equals and gethashcode, due to collisions, in particular while using dictionaries. if two object returns same hashcode, they are inserted in the dictionary with chaining. While accessing the item equals method is used.

When should we override GetHashCode?

If you're implementing a reference type, you should consider overriding the Equals method if your type looks like a base type, such as Point, String, BigNumber, and so on. Override the GetHashCode method to allow a type to work correctly in a hash table.

What is the purpose of GetHashCode?

The GetHashCode method provides this hash code for algorithms that need quick checks of object equality. For information about how hash codes are used in hash tables and for some additional hash code algorithms, see the Hash Function entry in Wikipedia. Two objects that are equal return hash codes that are equal.

How does GetHashCode work C#?

The GetHashCode method provides this hash code for algorithms that need quick checks of object equality. Syntax: public virtual int GetHashCode (); Return Value: This method returns a 32-bit signed integer hash code for the current object.


2 Answers

To summarise what was discussed in the comments:

Hashing is designed to provide a value that doesn't change for a given object, no matter what happens to it - hence it's best to depend only on readonly fields in your GetHashCode method.

Firstly, I would suggest making the name and lname field readonly, because they probably don't change in your usage scenario.

As for age, this is something that changes regularly, so probably best to store a DateTime for date of birth, which never changes. Then you can make that readonly too.

like image 197
Baldrick Avatar answered Oct 19 '22 02:10

Baldrick


If you change the value of a field, used in the hash calculation, after the object had been added to a hash based container like Dictionary or HashSet, you are essentially breaking the inner state of the container. Why is that? Because the object had been stored in a bucket corresponding to a hash value based on its initial state. When the state is changed, e.g. 'age' is modified, the object will continue to live in its old bucket in the hash container although this is not the correct bucket based on its current hash code. This can lead to pretty messy behaviour and a lot of headaches. I've written an article on this topic with some very specific examples, so you may want to check it out.

like image 38
Vasil Kosturski Avatar answered Oct 19 '22 02:10

Vasil Kosturski