Ekin Karadağ

Let’s continue our article, which we started by explaining the basic details of the subject in the first part, with examples from where we left off.

Here we see that although 3 empty objects are created, returned results are different. This is because the Equals method compares the references here. A new object named object1 was created and object1 was assigned to object2. The thing to pay attention to here is that object2 points to the same address as object1. When object3 was created, a new instance was created unlike object2. Therefore, since the place they point to is different, the Equals method returned false even though neither object was assigned a value.

Let’s do one more example for better understanding.

As you can see, the Equals method returned false because a and c objects derived from the car class have the same value but different references.

This is where the importance of overriding the Equals method comes into play. You can shape the Equals method to suit your purpose.

 

As can be seen from this example, the Equals method in the Car class has been overridden to prevent it from returning false results. In this way, the problem of returning false from objects whose references are different even though the data inside is the same has been eliminated.

So where does the GetHashCode method come into play?

Let’s start with an example.

As it can be seen, when the values of the 3 string values are the same, there is no change in the hash codes, but does the situation change for reference types? For example, even if the data of the objects derived from the car class are the same, it is seen that the hash codes are different.

As it is shown, the GetHashCode method, like the Equals method, may not return the desired results because it looks at the reference, not the data itself. This problem can be solved by overriding the GetHashCode method as we applied to the Equals method.

Let’s do an example before overriding and see what it looks like before and after overriding.

As it can be seen, although we have assigned 3 objects, we see 2 in the output. Because the references of a and b objects are the same, the hash calculation gave the same result. Because C’s reference is different from a and b, the hash result came out differently and returned 2. Now let’s make changes to the GetHashCode method.

Thanks to the GetHashCode method overridden above, the hash codes of the data it contains are now calculated rather than their references. Let’s go back to our HashSet.

As you can see, the hash calculation has changed and since the hash code of all 3 objects is the same, the output is 1.

So what would be the result if I changed the return value of my GetHashCode method to 0 and returned the hash code of each object as 0?

The result is still 1 because all 3 objects have a hash value of 0. So what would happen if I added a new object derived from the car class to my HashSet and gave it different values?

In fact, although I assigned all the hash codes to 0, it detected the last object I added differently. Because although the hash codes are the same, when the comparison is made in the Equals method, it returned false and thus our output was 2 because it was considered as a different object.

In this article, I tried to explain why Equals and GetHashCode methods should be overridden, the difference between primitive types and reference types and their reflections.

Good coding to everyone…