Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq Except with custom IEqualityComparer

I am trying to find the difference between two generic lists, as in the example below. Even though t1 and t2 contain the same properties, they are not the same object, so I have need to implement an IEqualityComparer.

This appears to be working with this example, but the real class has several other properties and I also need to do the same with a few other class.

So I was wondering if I am re-inventing the wheel?

Is there an easier method of comparing all the properties of two objects? At the moment, I really only need to cope with class containing simple types, but it would be nice I have a comparer that worked with classes that contains instances of other classes.

void Main() {     var t1 = new Sizes { Name = "Test" , Size = 1} ;     var t2 = new Sizes { Name = "Test" , Size = 1} ;      var list1 = new List<Sizes>();     var list2 = new List<Sizes>();     list1.Add(t1);     list2.Add(t2);      var differences = list2.Except(list1 , new SizesComparer());         // differences should be empty. }   public class Sizes   {     public string Name { get;  set; }     public int    Size { get;  set; } }  public class SizesComparer : IEqualityComparer<Sizes>    {     bool IEqualityComparer<Sizes>.Equals(Sizes x, Sizes y)     {                     return (x.Name.Equals(y.Name) && x.Size.Equals(y.Size));             }      int IEqualityComparer<Sizes>.GetHashCode(Sizes obj)     {         if (Object.ReferenceEquals(obj, null))             return 0;                         return obj.Name.GetHashCode() + obj.Size;            } } 
like image 517
sgmoore Avatar asked Aug 12 '11 15:08

sgmoore


1 Answers

You could try something like:

var differences = list2.Where(l2 =>      !list1.Any(l1 => l1.Name == l2.Name && l1.Size == l2.Size)); 

Or if you prefer:

var differences = list2.Where(l2 =>      list1.All(l1 => l1.Name != l2.Name || l1.Size != l2.Size)); 
like image 122
Chris Snowden Avatar answered Sep 27 '22 20:09

Chris Snowden