【问题标题】:Getting List.Join to compare properly获取 List.Join 以正确比较
【发布时间】:2015-07-22 08:33:59
【问题描述】:

如果属性匹配正确,我正在尝试通过加入两个列表来创建一个列表。我正在使用以下命令:

FooList = TrackedStrings.Join (FooList,
                                str => str,
                                Foo => Foo.GetString (),
                                (str, Foo) => Foo,
                                new Comparer ())
                                .ToList ();

和下面的类比较:

public class Comparer : IEqualityComparer<string>
{
  public bool Equals (string x, string y)
  {
    return y.Contains (x);
  }

  public int GetHashCode (string str)
  {
    return str.GetHashCode ();
  }
}

现在,我的想法是我只想保留具有 GetString () 的项目,其中包含来自 TrackedStrings 的任何字符串。但是,它不起作用:比较器仅在字符串相等时才返回 true。例如,假设我们有两个列表:

List<string> TrackedActions = new List<string> { "Created", "Deleted" };
List<Foo> FooList = new List<FooList> { new Foo ("Created"), new Foo ("Deleted Something")};

使用当前命令,第二个 Foo 将从列表中删除 - 而不是匹配到 TrackedActions[1] 并被保留。

因此,我的问题是:为什么Comparer 没有按我预期的方式工作?

【问题讨论】:

    标签: c# list compare


    【解决方案1】:

    你不应该使用 IEqualityComparer 因为The Equals method is reflexive, symmetric, and transitive. MSDN

    在你的情况下它不是对称的Equals(a,b) != Equals (b,a)

    Glorfindel 的回答也不完全正确,因为它不是传递性的:

    Equals("abcd","bc") == true
    Equals("bcde", "bc") == true
    Equals("abcd","bcde") == false
    

    【讨论】:

      【解决方案2】:

      自定义比较器必须确保它定义的Equals 关系是symmetric。这意味着无论何时x.Equals(y)y.Equals(x),反之亦然。

      这样做的原因是您永远无法预测元素的比较顺序,即其中的哪一个被调用:

      aStringFromLeftList.Equals(aStringFromRightList)
      

      aStringFromRightList.Equals(aStringFromLeftList)
      

      因为您需要的关系既不是对称的也不是传递的,所以您不能使用比较器来解决您的问题。

      【讨论】:

      • 我明白了。我想我必须找到其他方法来组合这两个列表。
      • 您好,您的实现不是可传递的,但 Equals 应该是。
      【解决方案3】:

      您的比较器不工作是由于GetHashCode() 的实施 不管实现IEqualityComparer正确方式。

      比赛由

      完成
      1. 比较两个字符串的哈希码。在您的情况下,Deleted Something 肯定会使用Deleted 返回不同的哈希码
      2. 如果 (1) 相等,则使用 E​​quals() 再次比较,因为 HashCode 可能有冲突且不准确,但速度快。

      【讨论】:

        猜你喜欢
        • 2020-05-29
        • 1970-01-01
        • 2018-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多