c# - 我正在为字符串实现 CaseAccentInsensitiveEqualityComparer。我不确定如何实现 GetHashCode

标签 c# .net string string-comparison

我的代码是这样的:

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 , IgnoreNonSpaceIgnoreCase obj 的版本这样我就可以返回它的HashCode .

我可以从 obj 中删除变音符号和大小写我自己然后返回它的hashcode ,但我想知道是否有更好的选择。

最佳答案

GetHashCode() 中返回 0 有效(正如@Michael Perrenoud 所指出的),因为 DictionariesHashMaps 调用 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/

相关文章:

c# - 动态更改月份列表

c# - 如何使用 LINQ 更改多个对象中的相同属性?

c# - MySQL 到 MS ACCESS 2007?

c# - 简易喷油器 : Cyclic Graph Error

arrays - 在 Rust 中将 u8 数组转换为 base64 字符串

java - 为什么字符串在许多编程语言中都是不可变的?

c# - 更改数据库迁移中的存储过程 EF 6 Code First - 如何将 null 作为参数的默认值传递

c# - 可以在给定 AutomationId 值的情况下实例化 AutomationElement 类型吗?

c# - 动态调用具有复杂参数的方法 (C#)

string - 寻找连续重复序列的算法