C # Implementing Equals method correctly and how to implement GetHashCode method

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Crystal_Message { class Person { private string firstName =""; private string lastName= ""; private string phone=""; public Person(string firstName, string lastName, string phone) { this.FirstName = firstName; this.LastName = lastName; this.PhoneNumber = phone; } public string FirstName { get { return firstName; } private set { if (string.IsNullOrWhiteSpace(value)){ throw new ArgumentNullException("Must Include First Name"); } this.firstName = value; } } public string LastName { get { return lastName; } private set { if (string.IsNullOrWhiteSpace(value)){ throw new ArgumentNullException("Must Include Last Name"); } this.lastName = value; } } public string PhoneNumber { get { return phone; } private set { if (string.IsNullOrWhiteSpace(value)){ throw new ArgumentNullException("Must Include Phone Number"); } this.phone = value; } } public override string ToString() { return "First Name: " + this.FirstName + " " + " Last Name: " + this.LastName + " " + " Phone Number: " + this.PhoneNumber; } public override bool Equals(object obj) { if(obj == null) { return false; } Person testEquals = obj as Person; if((System.Object)testEquals == null) { return false; } return (this.firstName == testEquals.firstName) && (this.lastName == testEquals.lastName) && (this.phone == testEquals.phone); } /* public override int GetHashCode() { return } */ } } 

I followed the MSDN recommendations. Two questions:

  • Did I use the equals method correctly?
  • Can someone show me how to implement GetHashCode correctly for my class? MSDN does x ^ y, but I cannot do this for my own.
+6
source share
3 answers

A more common method than simple xor hash codes, as stated in Philippe's answer, is to use a more complex formula to combine them. Multiply the hash codes of individual fields by different numbers, for example:

 public override int GetHashCode() { unchecked { return (firstName.GetHashCode() * 33 ^ lastName.GetHashCode()) * 33 ^ phone.GetHashCode(); } } 

(Note that the keyword is unchecked : integer overflow is expected here, and silence is precisely defined behavior.)

This will probably not affect the specific types you are dealing with, but overall it is better. Consider a simple type containing only two integer values. Consider also that the implementation of int GetHashCode() simply returns its own value. If you use simple xor to combine values, you will have many hash collisions for normal code: the simplest example is that each pair of two identical values โ€‹โ€‹will generate the same hash code of zero.

The calculation here is actually the calculation performed by Tuple<T1, T2, T3> . I did not write it the way Microsoft did, but the actual calculations and numbers should be the same.

+1
source

Well, in order not to run into any problems, GetHashCode should use all the members that Equals uses, and vice versa.

So in your case:

 public override int GetHashCode() { return firstName.GetHashCode() ^ lastName.GetHashCode() ^ phone.GetHashCode(); } 
+6
source

Itโ€™s better to keep in mind what the purpose of these two methods is: With equal YOU, determine under what circumstances two instances of your class should be considered, well, equal. Therefore, if it is indicated in your case, if the name, surname and phone number are equal, then this is true. The hash method, in turn, is used to sort or distribute instances, for example. in the hash map. It should be fast and good enough to avoid unwanted clustering. Therefore, you often see values โ€‹โ€‹multiplied by simple hash functions. You must ensure that the same objects have the same hash code, but not vice versa. Thus, different objects can have the same hash code.

+1
source

Source: https://habr.com/ru/post/988644/


All Articles