-2

I was looking around for a way to have a dictionary key/hash set string be case insensitive. I found many answers around on SO and even on the MS website.

From what I've seen, it seems like the answers are saying that by setting the IEqualityComparer<TKey> to StringComparer.CurrentCultureIgnoreCase (or something similar) for Dictionary and HashSet, this will make it as if the key set will be case insensitive. But no, they are saying that it sets the equality operator, which is different.

Hash sets that I'm familiar with convert the key object into a hashed numeric value which is then used to access a bucket that may contain the key that you are looking for. Then the equality operator is then used to check if that bucket actually contains the value you are looking for.

If this is the case, then it would be conceivable that a and A could be in different buckets, thus allowing the two items to be added without conflict, or checked upon and not finding the other. I have to assume that this is not the case as this would break a lot of code out there, so what is really happening here? What's happening behind the curtain?

Adrian
  • 10,246
  • 4
  • 44
  • 110
  • https://dotnetfiddle.net/Dv0HeC – Camilo Terevinto Jun 02 '22 at 19:54
  • 2
    If you take a closer look at the equality comparer interface it has two methods. Equals() and GetHashcode(). The two mentioned collections use the corresponding hash code method to generate the bucket number and the ignore case comparer produces the same number if two strings only differ by case. – Oliver Jun 02 '22 at 19:56
  • Thx @Oliver, I guess I'm confused as `StringComparer.CurrentCultureIgnoreCase` is an enum and `IEqualityComparer` is an interface. How is the enum being converted? – Adrian Jun 02 '22 at 20:35
  • 2
    I think you mean `StringComparison` is an enum. It just a helper parameter in a few places that will within the method pick the corresponding static comparer out of `StringComparer` and `StringComparer.CurrentCultureIgnoreCase` is a comparer. – Oliver Jun 03 '22 at 07:25
  • Right @Oliver. I had just done a blind find on the symbol and then did a find definition on it. Didn't look at the context carefully when I did that. Thx. – Adrian Jun 03 '22 at 14:10

1 Answers1

0

In .NET, two objects that are "equal" (and used as hashing keys) must generate the same hash code. So if you create a dictionary with a case-insensitive comparer, then a and A will definitely map to the same "bucket". Where that happens is in the object that StringComparer.CurrentCultureIgnoreCase returns, which generates hash codes in such a way that the equality relationship is preserved.

Note that it's possible for two objects that are not equal to generate the same hash code, but the Dictionary class first checks hash codes to see if two keys could be equal, and if they can, then checks to see if they are equal.

D Stanley
  • 149,601
  • 11
  • 178
  • 240