Linq 除了忽略自定义比较器?
Linq Except ignoring Custom comparer?
在这个玩具代码中:
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
看起来这个案子并没有被忽视。此外,当我 运行 它处于调试状态并在 Customer Comparer 中对 string.Equals 的调用处设置断点时,断点从未命中,尽管代码 运行 并且我得到了我发布的结果.我期望没有结果,因为如果忽略大小写,序列是相等的。
我猜我做错了什么,但我需要第二双眼睛才能发现它。
Rui Jarimba 关于使用 StringComparer.OriginalIgnoreCase 的建议有效。
调试您的代码显示调用了 GetHashCode() 而不是 Equals()。
我认为这是因为两个相等的对象必须具有相等的哈希码并且 return 来自 Equals() 的 true。如果哈希码不同,则它们不可能相等,因此无需 运行 Equals() 函数。
如果散列函数不区分大小写,您的代码将有效,obj.ToUpper().GetHashCode()。
修改你的比较器:
public int GetHashCode(string obj)
{
return 0;
}
现在所有项目都将具有相同的哈希值:0
- 这意味着项目 x
和 y
可能 相同,因此调用Equals
为必填项。
但是,不推荐这样做,因为在 GetHashCode 中只返回 0 会导致性能问题。
最好的选择是使用内置的 StringComparer.OrdinalIgnoreCase
相等比较器。
.NET Framework 已经提供了一个 StringComparer Class,它使用特定的大小写和基于文化或顺序的比较规则 - 因此在这种情况下无需创建自定义比较器。
这会起作用:
var x = new string[] { "abc", "DEF" };
var y = new string[] { "ABC", "def" };
var z = x.Except(y, StringComparer.OrdinalIgnoreCase);
在这个玩具代码中:
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
看起来这个案子并没有被忽视。此外,当我 运行 它处于调试状态并在 Customer Comparer 中对 string.Equals 的调用处设置断点时,断点从未命中,尽管代码 运行 并且我得到了我发布的结果.我期望没有结果,因为如果忽略大小写,序列是相等的。
我猜我做错了什么,但我需要第二双眼睛才能发现它。
Rui Jarimba 关于使用 StringComparer.OriginalIgnoreCase 的建议有效。
调试您的代码显示调用了 GetHashCode() 而不是 Equals()。
我认为这是因为两个相等的对象必须具有相等的哈希码并且 return 来自 Equals() 的 true。如果哈希码不同,则它们不可能相等,因此无需 运行 Equals() 函数。
如果散列函数不区分大小写,您的代码将有效,obj.ToUpper().GetHashCode()。
修改你的比较器:
public int GetHashCode(string obj)
{
return 0;
}
现在所有项目都将具有相同的哈希值:0
- 这意味着项目 x
和 y
可能 相同,因此调用Equals
为必填项。
但是,不推荐这样做,因为在 GetHashCode 中只返回 0 会导致性能问题。
最好的选择是使用内置的 StringComparer.OrdinalIgnoreCase
相等比较器。
.NET Framework 已经提供了一个 StringComparer Class,它使用特定的大小写和基于文化或顺序的比较规则 - 因此在这种情况下无需创建自定义比较器。
这会起作用:
var x = new string[] { "abc", "DEF" };
var y = new string[] { "ABC", "def" };
var z = x.Except(y, StringComparer.OrdinalIgnoreCase);