在此玩具代码中:
void Main()
{
var x = new string[] {"abc", "DEF"};
var y = new string[] {"ABC", "def"};
var c = new CompareCI();
var z = x.Except(y, c);
foreach (var s in z) Console.WriteLine(s);
}
private class CompareCI : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return string.Equals(x, y, StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(string obj)
{
return obj.GetHashCode();
}
}
似乎Except方法忽略了我的客户比较器。我得到这些结果:
abc
DEF
该案件似乎未被忽略。另外,当我在调试下运行它并在对string的调用处放置一个断点时,在客户比较器中等于断点,尽管代码已运行并且得到了发布的结果,但断点从未命中。我希望没有结果,因为如果忽略大小写,顺序是相等的。
猜猜我做错了什么,但是我需要第二只眼睛才能发现它。
答案 0 :(得分:1)
调试代码显示,调用了GetHashCode(),但未调用Equals()。
我认为这是因为两个相等的对象必须具有相等的哈希码,并且从Equals()返回true。如果哈希码不同,则它们不能相等,因此无需运行Equals()函数。
如果哈希函数不区分大小写,obj.ToUpper()。GetHashCode(),您的代码将起作用。
答案 1 :(得分:1)
.NET Framework已经提供了StringComparer Class,它使用特定的大小写和基于区域性的或有序的比较规则-因此,在这种情况下,无需创建自定义比较器。
这将起作用:
var x = new string[] { "abc", "DEF" };
var y = new string[] { "ABC", "def" };
var z = x.Except(y, StringComparer.OrdinalIgnoreCase);
答案 2 :(得分:0)
Rui Jarimba建议使用StringComparer.OriginalIgnoreCase起作用。
答案 3 :(得分:0)
修改比较器:
public int GetHashCode(string obj)
{
return 0;
}
现在所有项目将具有相同的哈希值:0
-这意味着项目x
和y
可能相同,因此调用Equals
是必需的。
但是,不建议这样做,因为在GetHashCode中仅返回0会导致性能问题。
最好的选择是使用内置的StringComparer.OrdinalIgnoreCase
相等比较器。