I'm implementing a CaseAccentInsensitiveEqualityComparer for Strings. I'm not sure how to implement the GetHashCode
.net, c#, string, string-comparison
Solution
Returning 0 inside `GetHashCode()` works (as pointed out by @Michael Perrenoud) because `Dictionaries` and `HashMaps` call `Equals()` just if `GetHashCode()` for two objects return the same values. The rule is, GetHashCode() must return the same value if objects are equal. The drawback is that the `HashSet` (or `Dictionary`) performance decreases to the point it becomes the same as using a List. To find an item it has to call `Equals()` for each comparison. A faster approach would be converting to Accent Insensitive string and getting its hashcode.
Code to remove accent (diacritics) from this post
static string RemoveDiacritics(string text)
{
return string.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
UnicodeCategory.NonSpacingMark)
).Normalize(NormalizationForm.FormC);
}
Comparer code:
public class CaseAccentInsensitiveEqualityComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) == 0;
}
public int GetHashCode(string obj)
{
return obj != null ? RemoveDiacritics(obj).ToUpperInvariant().GetHashCode() : 0;
}
private string RemoveDiacritics(string text)
{
return string.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
UnicodeCategory.NonSpacingMark)
).Normalize(NormalizationForm.FormC);
}
}
Problem
My code is like this: ``` public class CaseAccentInsensitiveEqualityComparer : IEqualityComparer<string> { public bool Equals(string x, string y) { return string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) == 0; } public int GetHashCode(string obj) { // not sure what to put here } } ``` I know the role of `GetHashCode` in this context, what I'm missing is how to produce the `InvariantCulture`, `IgnoreNonSpace` and `IgnoreCase` version of `obj` so that I can return it's `HashCode`. I could remove diacritics and the case from `obj` myself and then return it's `hashcode`, but I wonder if there's a better alternative.