GetHashCode implementation throws an exception
ID |
vbnet.correctness.exception_in_gethashcode |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Error Handling |
Language |
VB.NET |
Description
Reports a Throw statement, at any nesting depth, inside a parameterless Function GetHashCode() As Integer member. This covers both the unfinished Throw New NotImplementedException() stub and a deliberate guard that refuses to hash an object whose fields are not populated. A GetHashCode that always returns a number, combining whatever field values are present, is not reported.
Rationale
GetHashCode must be total: every object has to yield some integer. Dictionary, HashSet, Distinct, GroupBy and ToLookup call it on insertion and on every lookup, so a throwing implementation makes the type unusable as a key and the failure appears at an arbitrary collection operation rather than at the defective member. Guarding on an unpopulated field is the more insidious variant: the object hashes correctly early on, then the same instance throws after being reset or partially loaded, and the exception escapes from whichever caching, grouping or serialization layer happened to hash it. A hash code is only required to be consistent and to agree with Equals, never to be meaningful, so there is nothing an exception can protect here.
The following code illustrates the pattern detected by this rule:
Public Overrides Function GetHashCode() As Integer
' FLAGGED: GetHashCode implementation throws an exception
Throw New NotImplementedException()
End Function
Remediation
Always return a value. Combine the fields that participate in Equals with HashCode.Combine(…), or with Xor over each field’s own hash code, treating a Nothing field as a fixed constant such as 0 rather than dereferencing it. Replace a NotImplementedException stub with a real implementation derived from the same fields Equals compares. If a member should reject an object that is not fully initialized, put that check in an ordinary method or property and leave GetHashCode non-throwing.