如何覆盖 C# 中两个字符串的一般比较
How to override general comparison for two strings in C#
我有一个类似下面 link 的问题,但要复杂得多:
Ignoring accented letters in string comparison
我有一本字典,里面有一些值,例如:
{[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]} 它 returns 它不存在。
如何实现对我的代码的响应?
string.Compare(s1, s2, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace);
另一方面,正如我的问题标题,我如何在我的应用程序中覆盖一般(或主要)字符串比较方法?
所以,结合 linked answer for removal of accents and diacritics,你可以制作一个 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
有一些有趣的重载,因此 中建议的第一个解决方案可用于 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);
我有一个类似下面 link 的问题,但要复杂得多: Ignoring accented letters in string comparison
我有一本字典,里面有一些值,例如:
{[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]} 它 returns 它不存在。
如何实现对我的代码的响应?
string.Compare(s1, s2, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace);
另一方面,正如我的问题标题,我如何在我的应用程序中覆盖一般(或主要)字符串比较方法?
所以,结合 linked answer for removal of accents and diacritics,你可以制作一个 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
有一些有趣的重载,因此 中建议的第一个解决方案可用于 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);