在两个列表上使用联合没有按预期工作

Using union on two lists is not working as expected

我已经阅读了大约 30 篇关于这个主题的帖子,认为我完全按照你的指示去做了。

这是我正在使用的class:

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 的列表。我找到了列表的联合方法并试了一下。

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 }

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

问题是编译器不知道如何比较两个 UserID objects.It 使用默认的相等比较器比较你的对象 references.So 即使它们有相同的 user_id 他们被视为不同,因为引用不同。

您需要通过覆盖 class 中的 EqualsGetHashCode 方法告诉编译器根据 user_id 属性 比较您的对象,或者实施 [IEqualityComparer].1

Union 会删除重复项(参见 here)。这就是它与 Concat.

的不同之处

然而,要做到这一点,需要能够按照您期望的方式比较两个序列中的项目(因为 UserId 的两个内部值设置为 10 的实例是相等的) .

为此,要么提供相等比较器,要么在 UserId class 上实现 IEquatable。 MSDN 文章有一个在 Product class.

上执行此操作的示例

正如 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);

瞧!我有我的,"union"。 myresult 仅包含两个列表中的唯一元素。