Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ到对象列表的差异_C#_Linq - Fatal编程技术网

C# 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通用列表,我想用一种简单的方法来获取列表1中不在列表2中的所有EmailAddress对象

我正在考虑与Linq进行某种形式的左外连接,但我对如何设置有点困惑。我也愿意找到更好的解决方案


更新:我应该注意到这些是我的“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;