问题
I have 2 IList<T>
of the same type of object ItemsDTO
. I want to exclude one list from another. However this does not seem to be working for me and I was wondering why?
IList<ItemsDTO> related = itemsbl.GetRelatedItems();
IList<ItemsDTO> relating = itemsbl.GetRelatingItems().Except(related).ToList();
I'm trying to remove items in related
from the relating
list.
回答1:
Since class is a reference type, your ItemsDTO
class must override Equals
and GetHashCode
for that to work.
回答2:
From MSDN:
Produces the set difference of two sequences by using the default equality comparer to compare values.
The default equality comparer is going to be a reference comparison. So if those lists are populated independently of each other, they may contain the same objects from your point of view but different references.
When you use LINQ against SQL Server you have the benefit of LINQ translating your LINQ statement to a SQL query that can perform logical equality for you based on primary keys or value comparitors. With LINQ to Objects you'll need to define what logical equality means to ItemsDTO
. And that means overriding Equals()
as well as GetHashCode()
.
回答3:
Except works well for value types. However, since you are using Ref types, you need to override Equals
and GethashCode
on your ItemsDTO
in order to get this to work
回答4:
I just ran into the same problem. Apparently .NET thinks the items in one list are different from the same items in the other list (even though they are actually the same). This is what I did to fix it:
Have your class inherit IEqualityComparer<T>, eg.
public class ItemsDTO: IEqualityComparer<ItemsDTO>
{
public bool Equals(ItemsDTO x, ItemsDTO y)
{
if (x == null || y == null) return false;
return ReferenceEquals(x, y) || (x.Id == y.Id); // In this example, treat the items as equal if they have the same Id
}
public int GetHashCode(ItemsDTO obj)
{
return this.Id.GetHashCode();
}
}
来源:https://stackoverflow.com/questions/9297997/linq-except-method-does-not-work