I recently discovered that Visual Studio 2017 can auto-generate overrides for Equals
and GetHashCode
, but I was wondering why the GetHashCode
implementation is not in an unchecked block?
I made a simple class with two public string properties Foo and Bar, and the generated GetHashCode
implementation is shown below.
public override int GetHashCode()
{
var hashCode = -504981047;
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Foo);
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Bar);
return hashCode;
}
I was under the impression the unchecked for GetHashCode
implementations was important because it was very likely to overflow, and we don't want any overflow exceptions because it's fine if it wraps around.
By default C# projects do not check for overflow and underflow.
Right click on the project, Select Properties
, On the Build
Tab at the bottom select Advanced...
, Check the box labeled Check for arithmetic overflow/underflow
Now the default behavior is to throw System.OverflowException
if there is ever an overflow not in an explicit unchecked
block.
If you auto-generate overrides for Equals
and GetHashCode
with overflow checking turned on for the project, then the unchecked block is there as expected
public override int GetHashCode()
{
unchecked
{
var hashCode = -504981047;
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Foo);
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Bar);
return hashCode;
}
}