【问题标题】:Using union on two lists is not working as expected在两个列表上使用联合没有按预期工作
【发布时间】:2015-01-16 00:01:38
【问题描述】:

我已经阅读了大约 30 篇关于此主题的帖子,并且认为我完全按照您的指示进行了操作。

这是我正在使用的课程:

public class UserID
{
    public int user_id { get; set; }
    public bool exists { get; set; }
}

我创建了两个不错的列表。

List<UserID> List1 = new List<UserID>();
List<UserID> List2 = new List<UserID>();

我已成功填充两个列表。

我正在尝试获取唯一用户 ID 的列表。我找到了列表的 union 方法并试了一下。

List<UserID> ResultList = new List<UserID>();

ResultList = List1.Union(List2).ToList();

这就是问题所在。在此处运行的最后一行之后,ResultList 只是放在一起的两个列表。

List1 有 { 10, 20, 30, 40 } List2 有 { 10, 30, 40, 50, 60 }

我期待工会给我:

结果列表 = { 10, 20, 30, 40, 50, 60 }

但它给了我:

结果列表 = { 10, 20, 30, 40, 10, 30, 40, 50, 60 }

我做错了什么?我读过很多不同的帖子,它们都说了同样的话——基本上是用法。我没有正确使用它吗?我没有收到任何错误,只是没有给我我期望的工会。

【问题讨论】:

  • Union 会将 2 个列表添加到一起,而不检查它们的值或删除重复项。你可以在联合之后调用 Distinct() ,它会给你没有重复的唯一值

标签: c# linq c#-4.0


【解决方案1】:

问题是编译器不知道如何比较两个 UserID 对象。它使用默认相等比较器通过引用比较您的对象。所以即使它们具有相同的 user_id,它们也被视为不同,因为引用是不同。

您需要通过在您的类中覆盖 EqualsGetHashCode 方法或实现 [IEqualityComparer].1 来告诉编译器根据 user_id 属性比较您的对象。

【讨论】:

    【解决方案2】:

    Union 确实删除了重复项(请参阅here)。这就是它与Concat 的不同之处。

    但是,这样做需要能够以您期望的方式比较两个序列中的项目(因为内部值设置为 10 的两个 UserId 实例是相等的)。

    为此,要么提供一个相等比较器,要么在 UserId 类上实现 IEquatable。 MSDN 文章中有一个在 Product 类上执行此操作的示例。

    【讨论】:

      【解决方案3】:

      正如 Selman22 建议的那样,我需要使用 [IEqualityComparer]。

      我将此添加到我的代码中。

      public class CompareUserIDs : IEqualityComparer<UserID>
      {
          public bool Equals(UserID x, UserID y)
          {
              return x.user_id.Equals(y.user_id);
          }
      
          public int GetHashCode(UserID obj)
          {
              return obj.user_id.GetHashCode();
          }
      }
      

      然后我这样称呼它:

      IntermediateResult = List1.Union(List2).ToList();
      IEqualityComparer<UserID> customComparer = new CompareResultTables();
      IEnumerable<UserID> myresult = IntermediateResult.Distinct(customComparer);
      

      瞧!我有我的“工会”。 myresult 仅包含两个列表中的唯一元素。

      【讨论】:

      • 您的比较器不处理 null UserID 对象,它几乎肯定应该处理。
      猜你喜欢
      • 1970-01-01
      • 2019-06-22
      • 2011-08-27
      • 1970-01-01
      • 1970-01-01
      • 2014-04-23
      • 2017-08-22
      • 2022-06-22
      • 2018-04-24
      相关资源
      最近更新 更多