5

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.

Yuck
  • 49,664
  • 13
  • 105
  • 135
Nugs
  • 5,503
  • 7
  • 36
  • 57

4 Answers4

11

Since class is a reference type, your ItemsDTO class must override Equals and GetHashCode for that to work.

Magnus
  • 45,362
  • 8
  • 80
  • 118
1

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().

Yuck
  • 49,664
  • 13
  • 105
  • 135
0

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();
  }
}
Aximili
  • 28,626
  • 56
  • 157
  • 216
0

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

gprasant
  • 15,589
  • 9
  • 43
  • 57