【问题标题】:Linq Except ignoring Custom comparer?Linq 除了忽略自定义比较器?
【发布时间】:2018-10-04 13:35:57
【问题描述】:

在这个玩具代码中:

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.Equals 的调用放置一个断点时,断点从未命中,尽管代码运行并且我得到了我发布的结果。我期望没有结果,因为如果忽略大小写,序列是相等的。

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

【问题讨论】:

  • 不需要自定义比较器......试试var z = x.Except(y, StringComparer.OrdinalIgnoreCase);
  • @RuiJarimba 不知道我是怎么错过的!谢谢!
  • 啊,我以为这只是一个例子。但如果它真的只是一个不区分大小写的字符串比较,那么是的,直接在Except 调用中使用StringComparison.OrdinalIgnoreCase,因为它已经是一个IEqualtiyComparer&lt;string&gt;

标签: c# linq except


【解决方案1】:

调试您的代码显示调用了 GetHashCode() 但没有调用 Equals()。

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

如果散列函数不区分大小写,obj.ToUpper().GetHashCode(),您的代码就可以工作。

【讨论】:

    【解决方案2】:

    Rui Jarimba 建议使用 StringComparer.OriginalIgnoreCase 有效。

    【讨论】:

    • 也许它有效,但它不是您问题的答案。
    • 是的,这应该作为评论发布,而不是作为答案发布。我会尽快添加我的答案
    【解决方案3】:

    修改你的比较器:

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

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

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

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

    【讨论】:

      【解决方案4】:

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

      这将起作用:

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

      【讨论】:

      • @JohnSmith 所以你决定否决接受的答案?是的,你是对的,它没有解释为什么断点没有被命中 - 但它是 OPs 问题的最佳解决方案,IMO。无需重新设计轮子并实现 .NET Framework 中已有的功能
      猜你喜欢
      • 2010-11-03
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      • 2012-04-30
      • 2021-11-21
      • 2017-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多