在两个列表上使用union不能按预期工作

时间:2015-01-15 14:22:33

标签: c# linq c#-4.0

我已经阅读了关于这个主题的大约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的列表。我找到了列表的联合方法并给了它一个镜头。

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

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

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

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

我期待工会给我:

ResultList = {10,20,30,40,50,60}

但是它给了我:

ResultList = {10,20,30,40,10,30,40,50,60}

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

3 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:0)

Union会删除重复项(请参阅here)。这使它与Concat不同。

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

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

答案 2 :(得分:0)

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

瞧!我有我的,#34;工会&#34;。 myresult只包含两个列表中的唯一元素。