#1,143 – Implement IEquatable in a Generic Type

You can use the EqualityComparer<T> type to implement IEquatable<T> for a generic type.

In the example below, we implement IEquatable<TwoThings<T1,T2>> for our TwoThings<T1,T2> type.  The EqualityComparer<T> type is used to properly compare member data, regardless of the types.  Without this, the compiler wouldn’t know how to compare two T1 or two T2 objects.

    public class TwoThings<T1,T2> : IEquatable<TwoThings<T1,T2>>
        T1 thing1;
        T2 thing2;

        EqualityComparer<T1> comparer1 = EqualityComparer<T1>.Default;
        EqualityComparer<T2> comparer2 = EqualityComparer<T2>.Default;

        public TwoThings(T1 thing1, T2 thing2)
            this.thing1 = thing1;
            this.thing2 = thing2;

        // IEquatable
        public bool Equals(TwoThings<T1, T2> other)
            return (comparer1.Equals(thing1, other.thing1) &&
                    comparer2.Equals(thing2, other.thing2));

Now suppose that we construct this class using types that implement value equality.  The Equals method then behaves as we’d expect.

            Dog myDog = new Dog("Jack", 5);
            TwoThings<Dog, string> first = new TwoThings<Dog, string>(myDog, "Feisty");

            Dog otherDog = new Dog("Jack", 5);
            TwoThings<Dog, string> second = new TwoThings<Dog, string>(otherDog, "Feisty");

            // Returns true
            bool eq = first.Equals(second);