我想知道如何获取不属于同一类型的另一个列表的元素。
实施例
List<Person> list1;
List<Person> list2;
list1[0] = "A"
list1[1] = "B"
list1[2] = "C"
list1[3] = "D"
list2[0] = "C"
list2[1] = "D"
我想要一个包含元素A和B的新列表
我试图这样做,但它没有用。
var newList =list1.Except(list2).ToList();
答案 0 :(得分:2)
1)请注意Person
可能不是值类型,而是引用类型。因此,Except
不会比较值,而是引用。如果你想通过实例的属性应用“Except”逻辑(让我们说“Name”),那么使用这样的东西:
string[] valuesToExclude = list1.Select(person => person.Name).ToArray();
var newList = list2.Where(person => !valuesToExclude.Contains(person.Name)).ToList();
2)您也可以将IEqualityComparer<Person>
传递给Except
:
public class PersonComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
return Equals(x.Name, y.Name);
}
public int GetHashCode(Person obj)
{
return obj.Name.GetHashCode();
}
}
这是第二个参数,如:
var newList = list2.Except(list1, new PersonComparer()).ToList();
3)最后,值得注意的是,如果Person
是struct
(值类型),那么您的代码将按原样运行,假设所有属性匹配您正在除外的实例。例如:
public struct Person
{
public string Name { get; set; }
}
List<Person> list1 = new List<Person>
{
new Person { Name = "A" },
new Person { Name = "B" },
};
List<Person> list2 = new List<Person>
{
new Person { Name = "A" },
};
var newList = list1.Except(list2).ToList();
// "B" only
答案 1 :(得分:2)
您拥有的代码很可能无法正常工作,因为它正在进行参考比较,这意味着A
和B
是Person
个对象,并且每个属性具有相同的值{{1} }为true,A != B
为false。现在,如果我有;
A == B
因此,您可能希望定义自定义相等比较器。你可以这样做;
Person A = new Person();
Person B = A;
A == B // this is true now, that's the comparison Except is doing
然后打电话给Except,就像这样;
class PersonEqualityComparer : IEqualityComparer<Person>
{
public bool Equals(Person lhs, Person rhs)
{
return lhs.Name == rhs.Name;
}
public int GetHashCode(Person p)
{
return p.Name.GetHashCode();
}
}