如何找到两个IEnumerable对象之间的差异

7

我有两个GUID列表,分别如下:

IEnumerable<dynamic> userids = null;
IEnumerable<dynamic> lsCheckedUsers = null;

用户ID和lsCheckedUsers列表是使用Dapper从SQL数据库填充的。
现在,我希望找到所有不在lsCheckedUsers中的用户ID。
我尝试了以下方法:
var userdifference = userids.Where(i => !lsCheckedUsers.Contains(lsCheckedUsers));
var userdifference = userids.Except(lsCheckedUsers);

以上任何一种方法都不能实际返回这两者之间的差异。

如何获取在两个GUID中都不存在的差异?

我确定lsCheckedUsers中有一些与userids中相同的GUID。


2
“!lsCheckedUsers.Contains(lsCheckedUsers)” 这个语句并不是很有趣 - 它会一直保持常数(我认为是 false)... - Alexei Levenkov
5
СйаСй┐ућеIEnumerable<dynamic>УђїСИЇТў»IEnumerable<Guid>№╝їТў»тљдТюЅтјЪтЏа№╝Ъ - itsme86
4个回答

13

以下是正确的代码:

var userdifference = userids.Except(lsCheckedUsers);

如果你的两个 IEnumerable<dynamic> 集合都包含 Guids,那么这段代码将会正常工作。建议打印或检查每个集合中的项目以确保它们是 Guids

如果你期望传入的对象是 Guids,那么你应该使用 IEnumerable<Guid> 并将传入的项目强制转换为 Guids。这样做有助于避免潜在的错误。


使用动态对象时,比较未按预期工作。我将类型更改为实际的Guid,然后它就起作用了。 - user1526912
@user1526912:嗯,有趣。如果内部类型确实是“Guids”,那么它肯定应该作为“dynamic”工作。我用“IEnumerable<dynamic>”和“IEnumerable<Guid>”进行了测试(简单的测试--使用一些匹配和不匹配的“Guids”添加了几个“List<dynamic>”)。我想知道你是否将它们强制转换为“Guids”时进行了某种内部转换... - Ian Gardner
假设 userIds 为空,而 lsCheckedUsers 有一条记录。当使用 userids.Except(lsCheckedUsers) 时,结果将为空。但是,当我们调用 lsCheckedUsers.Except(userids) 时,将从 lsCheckedUsers 中获取一条记录。这可能会导致混淆。 - Oyun

2

Something along those lines..

var difference = list1.Where (e => !list2.Any(a => a == e))

1

1
你有:

var userdifference = userids.Where(i => !lsCheckedUsers.Contains(lsCheckedUsers));

但我想你的意思是:
var userdifference = userids.Where(i => !lsCheckedUsers.Contains(i));

更新:

对于因「引用」比较而标记这些答案为负分的每个人,请注意 Guid 是一种值类型,因此其相等性的评估方式不同。尝试进行以下简单测试来使自己信服:

var guid = Guid.NewGuid();
var guids = new[] { new Guid(guid.ToString()) };

Console.WriteLine(guids.Contains(guid));

你会看到结果是True。

只有当它们是相同引用时才会起作用。这两个列表都是从数据库中填充的。 - Vitor Canova
@VitorCanova 通常情况下是这样的,但 Guid 是一个结构体,其相等性的评估方式不同。自己试试看吧。 - itsme86
抱歉,我没有注意到。你为什么要使用动态类型? - Vitor Canova
刚刚在代码中查看了一下 Guid 的作用。它有一个“Equal”方法的实现,可以比较每个段。 - Vitor Canova

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接