如何在 C# 中重写两个字符串的常规比较

本文关键字:两个 字符串 比较 常规 重写 | 更新日期: 2023-09-27 18:37:21

我有一个类似于以下链接的问题,但要复杂得多:在字符串比较中忽略重音字母

我有一个字典和一些值,例如:

{[Ministère de l'économie, 139]}
{[Ministère des finances, 114]}

为了将新元素插入字典,作为相同的代码,我写了这个:

if (!dict.ContainsKey(str))
{  dict.Add(str, Convert.ToDouble(number)); }

但是当我想检查这个值的存在时:{[Ministère de l'economie, 139]} 它返回它不存在。

如何将此响应实现到我的代码中?

string.Compare(s1, s2, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace); 

另一方面,作为我问题的标题,如何在我的应用程序中覆盖通用(或主要)字符串比较方法?

如何在 C# 中重写两个字符串的常规比较

因此,结合删除重音符号和变音符号的链接答案,您可以制作一个IEqualityComparer<string>提供给字典:

public class IgnoreAccentsAndDiacriticsComparer:IEqualityComparer<string>
{
    public bool Equals(string left, string right)
    {
        if(left == null && right == null){ return true; }
        if(left == null || right == null){ return false; }
        return string.Equals(RemoveDiacritics(left), RemoveDiacritics(right));
    }
    public int GetHashCode(string txt)
    {
        return RemoveDiacritics(txt).GetHashCode();
    }
    static string RemoveDiacritics(string text)
    {
        string formD = text.Normalize(NormalizationForm.FormD);
        StringBuilder sb = new StringBuilder();
        foreach (char ch in formD)
        {
            UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(ch);
            if (uc != UnicodeCategory.NonSpacingMark)
            {
                sb.Append(ch);
            }
        }
        return sb.ToString().Normalize(NormalizationForm.FormC);
    }
}

现在,使用此比较器的实例构造字典:

var myDic = new Dictionary<string, int>(new IgnoreAccentsAndDiacriticsComparer())

并尝试添加一些带重音的内容:

myDic["Aimée"] = 1;

。然后读出来,没有重音:

Console.WriteLine(myDic["Aimee"]); //ŵôõ!

从 .NET 4.6 开始,有一些有趣的 CompareInfo 重载,因此 https://stackoverflow.com/a/368850/613130 中建议的第一个解决方案可以在IEqualityComparer<string>中使用:

public class StringComparerIgnoreDiacritics : IEqualityComparer<string>
{
    public static readonly StringComparerIgnoreDiacritics CurrentCulture = new StringComparerIgnoreDiacritics(CultureInfo.CurrentCulture.CompareInfo);
    public readonly CompareInfo CompareInfo;
    public StringComparerIgnoreDiacritics(CompareInfo compareInfo)
    {
        CompareInfo = compareInfo;
    }
    #region IEqualityComparer<string> Members
    public bool Equals(string x, string y)
    {
        return CompareInfo.Compare(x, y, CompareOptions.IgnoreNonSpace) == 0;
    }
    public int GetHashCode(string obj)
    {
        return CompareInfo.GetHashCode(obj, CompareOptions.IgnoreNonSpace);
    }
    #endregion
}

然后

var myDic = new Dictionary<string, int>(var myDic = new Dictionary<string, int>(new IgnoreAccentsAndDiacriticsComparer()).CurrentCulture);