Search code examples
c#observablecollectioniequalitycomparericomparable

Collections with user defined class - find differences


This is my model:

public class EventModel
{
    public DateTime? EVENT_DATE { get; set; }
    public decimal? EVENT_TYPE { get; set; }
    public string EVENT_DESCRIPTION { get; set; }
}

I fill this class into ObservableCollection<EventModel>. When I do that, I also deep-copy same collection. Then I want to compare these two collections in later use.

I would preferably use LINQ to do that, with something like

bool are_same = collection1.OrderBy(i => i).SequenceEqual(
                 collection2.OrderBy(i => i));

This means that both collections needs to be sorted and then compared to each other for finding differencies in ALL PROPERTIES.

There are a lot of examples for implementing IComparable & IEqualityComparer, but I'm confused about what I need and how.

I would appreciate If someone would show me how this can be done in C#.


Solution

  • If you simply want to check if the two collections are equal you need to define what equality is, for example by implementing IEqualityComparer<T>. This can also be done by implementing IEquatable<T> or or by overriding Equals(object) and GetHasCode. This can be done automatically by some refactoring tools:

    public sealed class EventModelEqualityComparer : IEqualityComparer<EventModel>
        {
            public bool Equals(EventModel x, EventModel y)
            {
                if (ReferenceEquals(x, y)) return true;
                if (ReferenceEquals(x, null)) return false;
                if (ReferenceEquals(y, null)) return false;
                if (x.GetType() != y.GetType()) return false;
                return Nullable.Equals(x.EVENT_DATE, y.EVENT_DATE) &&
                       x.EVENT_TYPE == y.EVENT_TYPE &&
                       x.EVENT_DESCRIPTION == y.EVENT_DESCRIPTION;
            }
    
            public int GetHashCode(EventModel obj)
            {
                unchecked
                {
                    var hashCode = obj.EVENT_DATE.GetHashCode();
                    hashCode = (hashCode * 397) ^ obj.EVENT_TYPE.GetHashCode();
                    hashCode = (hashCode * 397) ^ (obj.EVENT_DESCRIPTION != null ? obj.EVENT_DESCRIPTION.GetHashCode() : 0);
                    return hashCode;
                }
            }
        }
    

    To compare two collections to see if they contains the same items, but in arbitrary positions, you can use a HashSet.SetEquals:

    myCollection.ToHashSet(new EventModelEqualityComparer()).SetEquals(myOtherCollection);