繁体   English   中英

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

看起来这种情况并没有被忽略。 另外,当我在调试下运行它并在对string的调用处放置一个断点时,在客户比较器中等于断点,尽管代码已运行并且得到了发布的结果,但断点从未命中。 我期望没有结果,因为如果忽略大小写,则序列是相等的。

猜猜我做错了什么,但是我需要第二双眼睛才能发现它。

调试代码显示,调用了GetHashCode(),但未调用Equals()。

我认为这是因为两个相等的对象必须具有相等的哈希码,并从Equals()返回true。 如果哈希码不同,则它们不能相等,因此无需运行Equals()函数。

如果哈希函数不区分大小写,即obj.ToUpper()。GetHashCode(),则您的代码将起作用。

.NET Framework已经提供了StringComparer类该类使用特定的大小写和基于区域性的或有序的比较规则-因此,在这种情况下,无需创建自定义比较器。

这将起作用:

var x = new string[] { "abc", "DEF" };
var y = new string[] { "ABC", "def" };
var z = x.Except(y, StringComparer.OrdinalIgnoreCase);

Rui Jarimba的建议使用StringComparer.OriginalIgnoreCase起作用。

修改比较器:

public int GetHashCode(string obj)
{
    return 0;
}

现在所有项目将具有相同的哈希值: 0这意味着项目xy 可能相同,因此需要调用Equals

但是,不建议这样做,因为在GetHashCode中仅返回0会导致性能问题。

最好的选择是使用内置的StringComparer.OrdinalIgnoreCase相等比较器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM