我的代码是这样的:
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
}
}
我知道GetHashCode
的作用在这种情况下,我缺少的是如何生成 InvariantCulture
, IgnoreNonSpace
和 IgnoreCase
obj
的版本这样我就可以返回它的HashCode
.
我可以从 obj
中删除变音符号和大小写我自己然后返回它的hashcode
,但我想知道是否有更好的选择。
最佳答案
在 GetHashCode()
中返回 0 有效(正如@Michael Perrenoud 所指出的),因为 Dictionaries
和 HashMaps
调用 Equals( )
只是如果两个对象的 GetHashCode()
返回相同的值。
rule即,如果对象相等,GetHashCode() 必须返回相同的值。
缺点是 HashSet
(或 Dictionary
)性能下降到与使用 List 相同的程度。要找到一个项目,它必须为每次比较调用 Equals()
。
一种更快的方法是转换为不区分重音的字符串并获取其哈希码。
从 post 中删除重音(变音符号)的代码
static string RemoveDiacritics(string text)
{
return string.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
UnicodeCategory.NonSpacingMark)
).Normalize(NormalizationForm.FormC);
}
比较代码:
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);
}
}
关于c# - 我正在为字符串实现 CaseAccentInsensitiveEqualityComparer。我不确定如何实现 GetHashCode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13017660/