C# LINQ到对象列表的差异
我有两个EmailAddress通用列表,我想用一种简单的方法来获取列表1中不在列表2中的所有EmailAddress对象 我正在考虑与Linq进行某种形式的左外连接,但我对如何设置有点困惑。我也愿意找到更好的解决方案C# LINQ到对象列表的差异,c#,linq,C#,Linq,我有两个EmailAddress通用列表,我想用一种简单的方法来获取列表1中不在列表2中的所有EmailAddress对象 我正在考虑与Linq进行某种形式的左外连接,但我对如何设置有点困惑。我也愿意找到更好的解决方案 更新:我应该注意到这些是我的“EmailAddress”对象的自定义数据类型列表。您可以使用Except linq方法: var list1 = // First list generation var list2 = // Second list generation var
更新:我应该注意到这些是我的“EmailAddress”对象的自定义数据类型列表。您可以使用Except linq方法:
var list1 = // First list generation
var list2 = // Second list generation
var result = list1.Except(list2);
嗯,我相信人们会来到这里,给你一个更时髦、更灵巧的例子,但我的雇主只允许我们使用.NET2.0,所以
List<EmailAddress> ret = new List<EmailAddress>( );
foreach ( EmailAddress address in List1 )
{
if( !List2.Contains( address ) )
{
ret.Add( address );
}
}
list1.除了(list2)代码>
编辑:示例。列表列表1=新列表();
List list2=新列表();
List list3=list1.Except(list2.ToList();
由于列表1和列表2中的项目在用户眼中可能是相等的,但实际上是对不同实例的引用(它们不是相等的引用),因此这些答案中的大多数都不起作用
假设Address是EmailAddress的字符串属性,下面是一个左连接解决方案
IEnumerable<EmailAddress> query =
from a1 in list1
join a2 in list2 on a1.Address equals a2.Address into g
from x in g.DefaultIfEmpty()
where x == null
select a1;
IEnumerable查询=
来自列表1中的a1
将a2连接到a1上的列表2中。地址等于a2。地址转换为g
从g.DefaultIfEmpty()中的x开始
其中x==null
选择a1;
如果列表2包含列表1中的电子邮件地址,则仍然会将其添加到此场景中。无论出于何种原因,Contains()方法都不能按预期工作。这是因为您没有重写.Equals方法,所以您正在检查引用,不是值。我不确定如何实现重写的.Equals方法,但这至少在检查引用部分是有意义的。您可以使用对应用程序有意义的任何内容。可变对象的==运算符通常检查引用相等性。如果电子邮件地址相同,则.Equals方法可能返回true,而不管它们在内存中是否为同一对象。如果您正确重写Equals方法使其有意义,则它们将起作用。老实说,这样的代码只是使一个极其简单的操作过于复杂,除非有充分的理由不重写.Equals(我们无法知道)。不过,OP现在可以知道这些东西实际上是如何工作的,这很好。你能解释一下我是如何在这个场景中重写Equals方法的吗?重写Equals是一种将bug引入代码的好方法。该指南指出,“建议重写等于的任何类也重写System.Object.GetHashCode。”当然,凡人不会正确重写GetHashCode。接着是山丘。嗯,这是一件非常好的事情,只要你明白你在做什么。在这种情况下,这也很有意义。此外,如果您的类是不可变的,那么您可以继续重写==如果您愿意的话。即使OP有理由不能在其电子邮件地址
类型上重写Equals
/GetHashCode
,然后他们仍然可以使用LINQ的Except
方法并传入一个自定义IEqualityComparer
:例如,var onlyInList1=list1.Except(list2,myCustomEmailAddressComparer)代码>
List<String> list1 = new List<string>();
List<String> list2 = new List<string>();
List<String> list3 = list1.Except(list2).ToList();
IEnumerable<EmailAddress> query =
from a1 in list1
join a2 in list2 on a1.Address equals a2.Address into g
from x in g.DefaultIfEmpty()
where x == null
select a1;