在两个列表上使用联合没有按预期工作
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 中的 Equals
和 GetHashCode
方法告诉编译器根据 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 仅包含两个列表中的唯一元素。
我已经阅读了大约 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 中的 Equals
和 GetHashCode
方法告诉编译器根据 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 仅包含两个列表中的唯一元素。