2011-05-02 66 views
5

这可能是一个常见问题,而且我没有找到可行的解决方案来搜索其他问题(注意,我的C#和linq技能是有限的 - 所以一个简单的解决方案将不胜感激!)。C#比较两个列表,返回列表2中的新项目

这里是问题

我有2列出了使用对象。我想比较它们并返回list2中的所有NEW对象。

实施例:

链表类的List1; //包含存储在数据库中的3个对象

ObjectList List2; //包含与List1中相同的3个对象以及从网页添加的新对象(父对象已在网页上更新)

ObjectList List3; //应该做一个比较列表1和列表2,并在列表2返回新的对象(所以结果应该只是对象数量4)

注:

  • 的顺序并不重要。我只想要新对象
  • 通常,对象只能添加到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))); 

回答

14

使用此:

var list3 = list2.Except(list1); 

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

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

我喜欢这个比我的好:) – iain 2011-05-02 12:41:17

+0

这也将是很好的提[除过载(http://msdn.microsoft.com/en-us/library/system.linq。 enumerable.except.aspx),它使用'IEqualityComparer'实例来比较元素。 – Groo 2011-05-02 12:43:17

+0

嗨daniel.Thank你的答案。这实际上是我尝试的解决方案之一。但是我得到错误“CAn不隐式转换类型”RepositoryObject“tog”RepositoryObjectList“,这两种类型都来自我们的软件,但所有3个列表被声明为”RepositoryObjectList“ – Kim 2011-05-02 12:43:28

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/en-us/library/system.icomparable.aspx

+0

+1对于具有引用类型列表(而不是简单值类型)以及提及IComparable的示例。我发现几乎所有我使用的列表都是复杂的引用类型,因此我怀疑只涉及值类型的解决方案。 – 2016-06-19 22:23:10

2

下面是一个例子如何使用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
secondList.Except(firstList) 

其使用

public static IEnumerable<TSource> Except<TSource>(
    this IEnumerable<TSource> first, 
    IEnumerable<TSource> second 
) 

http://msdn.microsoft.com/en-us/library/bb300779.aspx

secondList.Except(firstList,new CustomComparer()) 

其使用

public static IEnumerable<TSource> Except<TSource>(
    this IEnumerable<TSource> first, 
    IEnumerable<TSource> second, 
    IEqualityComparer<TSource> comparer 
) 

http://msdn.microsoft.com/en-us/library/bb336390.aspx