C#比较两个列表,返回列表2中的新项

7
这可能是一个常见的问题,我搜索了其他问题但没有找到可行的解决方案(请注意,我的C#和linq技能有限-所以需要简单的解决方案!)。
这里是问题:
我有两个包含对象的列表。我想比较它们并返回List2中所有的新对象。
例子:
ObjectList List1; // 包含3个在数据库中存储的对象
ObjectList List2; // 包含与List1相同的3个对象和从网页添加的新对象(父对象在网页上更新)
ObjectList List3; // 应该比较List1和List2,并返回List2中的新对象(因此结果应该只是Object number 4)
注意:
顺序无关紧要,我只想要新的对象(s)
通常对象只会添加到List2。如果任何对象被删除(与List1进行比较),则应忽略它。(因此仅存在于List1中的对象不感兴趣)
感谢您提供任何建议或链接以前我在搜索中错过的问题。
编辑:
这里是第一次尝试使用Except的一个小例子(这返回了一个错误)。
我已经将它缩短了一点。该方法来自我们的软件,所以它们可能不为您所知。对此我很抱歉。
 // caDialogObjects = List1 (caDialogQLMLinks is the link to the objects)
RepositoryObjectList caDialogObjects = args.Object.GetConfiguration().GetObjectSet(caDialogQLMLinks);

// caObjectObjects = List2 (caObjectQLMLinks is the link to the objects)
RepositoryObjectList caObjectObjects = args.Object.GetConfiguration().GetObjectSet(caObjectQLMLinks);

// List 3
RepositoryObjectList caTotal;
caTotal = caObjectObjects.Except(caDialogObjects);
可行的解决方法 由于列表只是一个引用(而不是一个值),所以异常处理并不能奏效。可以使用第二个参数,但我得到了一个有效的 Linq 代码解决了问题:
RepositoryObjectList caNewCA = 
    new RepositoryObjectList(caDialogObjects.Where(item1 => 
         !caObjectObjects.Any(item2 => item1.Id == item2.Id)));

可能是两个列表之间的差异的重复问题。 - JSON
4个回答

17

使用此代码:

var list3 = list2.Except(list1);

这里使用了Except扩展方法,它返回list2中所有不在list1中的元素。
需要注意的是,Except返回一个IEnumerable<T>类型,其中Tlist1list2中对象的类型。
如果你需要list3的特定类型,你需要转换返回值。在最简单的情况下,目标类型具有可以处理IEnumerable<T>的构造函数:

RepositoryObjectList list3 = new RepositoryObjectList(list2.Except(list1));

我喜欢这个比我的好 :) - iain
同时提及Except重载也是一个不错的选择,它使用IEqualityComparer实例进行元素比较。 - vgru
嗨,丹尼尔。感谢你的回答。这实际上是我尝试过的解决方案之一。但是我收到了错误消息“无法隐式转换类型“RepositoryObject”为“RepositoryObjectList”。这两种类型都来自我们的软件。但是所有3个列表都被声明为“RepositoryObjectList”。 - Kim
可能是我的类型出了问题。我会查一下的。再次感谢。 - Kim
我已经编辑了这个问题并提供了一个小样本。不知道是否足够。这里有很多软件方法,可能会使它变得困难。但我会尝试所有好的建议,希望我能让它正常工作。谢谢! - Kim
显示剩余7条评论

4
   List<MyObject> objectList1 = new List<MyObject>();
   List<MyObject> objectList2 = new List<MyObject>();
   List<MyObject> objectList3 = objectList2.Where(o => !objectList1.Contains(o)).ToList();

只要 MyObject 实现了 IComparable 接口,这样做就没问题了。

http://msdn.microsoft.com/zh-cn/library/system.icomparable.aspx


+1 对于一个包含引用类型列表的示例,而不是简单值类型的示例,并且提到了IComparable,我表示赞同。我发现我处理的几乎所有列表都是复杂的引用类型,因此我对仅涉及值类型的解决方案持怀疑态度。 - Simon Elms

3

以下是使用LINQ实现该操作的示例:

List<int> l1 = new List<int>();
List<int> l2 = new List<int>();

l1.AddRange(new int[] {1, 2, 3, 5});
l2.AddRange(new int[] {1, 2, 3, 4});

// get only the objects that are in l2, but not l1
var l3 = l2.Except(l1);

第三个列表中只包含一个元素,即4。

1

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