Skip to main content
copy editing, code improvement
Source Link
Konrad Rudolph
  • 549.3k
  • 142
  • 967
  • 1.3k

Rules 1 & 3 are contradictory to me.

To a certain extent, they are. The reason is simple: if an object is stored in a hash table and, by changing its value, you change its hash then the hash table has lost the value and you can't find it again by querying the hash table. It— It is therefore important that while objects are stored in a hash table, they retain their hash value.

To realizeensure this it is often simplest to make hashable objects immutable, thus evadingside-stepping the whole problem wholly. ItBut it is howeveractually sufficient to make only those fields immutable that determine the hash value.

Consider the following example:

struct Person { public readonly string FirstName; public readonly string Name; public readonly DateTime Birthday; public int ShoeSize; } 

People rarely change their birthdayname, and most people never changeeven less frequently their name (except when marrying)birthday. However, their shoe size may grow arbitrarily, or even shrink. It is therefore reasonable to identify people using their birthday and name but not their shoe size. The hash value should reflect this:

public override int GetHashCode() { return FirstNameHashCode.GetHashCodeCombine() ^FirstName, Name.GetHashCode() ^, Birthday.GetHashCode(); } 

And remember to override Equals whenever you override GetHashCode (and vice-versa)!

Rules 1 & 3 are contradictory to me.

To a certain extent, they are. The reason is simple: if an object is stored in a hash table and, by changing its value, you change its hash then the hash table has lost the value and you can't find it again by querying the hash table. It is important that while objects are stored in a hash table, they retain their hash value.

To realize this it is often simplest to make hashable objects immutable, thus evading the whole problem. It is however sufficient to make only those fields immutable that determine the hash value.

Consider the following example:

struct Person { public readonly string FirstName; public readonly string Name; public readonly DateTime Birthday; public int ShoeSize; } 

People rarely change their birthday and most people never change their name (except when marrying). However, their shoe size may grow arbitrarily, or even shrink. It is therefore reasonable to identify people using their birthday and name but not their shoe size. The hash value should reflect this:

public int GetHashCode() { return FirstName.GetHashCode() ^ Name.GetHashCode() ^ Birthday.GetHashCode(); } 

Rules 1 & 3 are contradictory to me.

To a certain extent, they are. The reason is: if an object is stored in a hash table and, by changing its value, you change its hash then the hash table has lost the value and you can't find it again by querying the hash table. — It is therefore important that while objects are stored in a hash table, they retain their hash value.

To ensure this it is often simplest to make hashable objects immutable, thus side-stepping the problem wholly. But it is actually sufficient to make only those fields immutable that determine the hash value.

Consider the following example:

struct Person { public readonly string FirstName; public readonly string Name; public readonly DateTime Birthday; public int ShoeSize; } 

People rarely change their name, and even less frequently their birthday. However, their shoe size may grow arbitrarily, or even shrink. It is therefore reasonable to identify people using their birthday and name but not their shoe size. The hash value should reflect this:

public override int GetHashCode() { return HashCode.Combine(FirstName, Name, Birthday); } 

And remember to override Equals whenever you override GetHashCode (and vice-versa)!

Source Link
Konrad Rudolph
  • 549.3k
  • 142
  • 967
  • 1.3k

Rules 1 & 3 are contradictory to me.

To a certain extent, they are. The reason is simple: if an object is stored in a hash table and, by changing its value, you change its hash then the hash table has lost the value and you can't find it again by querying the hash table. It is important that while objects are stored in a hash table, they retain their hash value.

To realize this it is often simplest to make hashable objects immutable, thus evading the whole problem. It is however sufficient to make only those fields immutable that determine the hash value.

Consider the following example:

struct Person { public readonly string FirstName; public readonly string Name; public readonly DateTime Birthday; public int ShoeSize; } 

People rarely change their birthday and most people never change their name (except when marrying). However, their shoe size may grow arbitrarily, or even shrink. It is therefore reasonable to identify people using their birthday and name but not their shoe size. The hash value should reflect this:

public int GetHashCode() { return FirstName.GetHashCode() ^ Name.GetHashCode() ^ Birthday.GetHashCode(); }