Skip to content

StringComparers' GetHashCode yield unexpected results when comparing null characters string and empty string #28447

@Gnbrkm41

Description

@Gnbrkm41

From: https://stackoverflow.com/questions/54243461/stringcomparer-invariantcultureignorecase-equals-vs-gethashcode-disagree-for-equ

Another report on Developer community: https://developercommunity.visualstudio.com/content/problem/430327/stringcomparers-may-return-different-hashcodes-for.html

Docs on string class state that:
Null characters are ignored when performing culture-sensitive comparisons between two strings, including comparisons using the invariant culture.

Also, docs on IEqualityComparer interface state that: Implementations are required to ensure that if the Equals(T, T) method returns true for two objects x and y, then the value returned by the GetHashCode(T) method for x must equal the value returned for y.

However, for all the StringComparers GetHashCode methods (except Ordinal/OrdinalInvariantCase, which it should take null characters into account) they do not consider the fact that if a string only consists of null characters \u0000 it should be treated as if it were string.Empty.

For example, calling StringComparer.InvariantCulture.Equals method with string.Empty and new string('\0', length) returns true, and this is true for string.Empty.Equals(new string('\0', length), StringComparison.InvariantCultureIgnoreCase)) as well.

On the other hand, calling StringComparer.GetHashCode method with string.Empty and new string('\0', length) does not result in same hashcode. The hashcode of string.Empty is 0 and string made out of null characters is not. This contradicts with the statement from IEqualityComparer document.

Current implementation of GetHashCodeOfStringCore method (Which I believe is the actual implementation of string.GetHashCode and StringComparer.GetHashCode methods) seem to always return 0 if the length of the string is 0. if not, it appears to do some pointer magic to get near-unique hashcode for the string.

Shouldn't the GetHashCode(StringComparison) method return '0' for strings made out of null characters as well, if the parameter is not StringComparison.Ordinal/OrdinalIgnoreCase?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions