You want to implement IEquatable<T>
when your type has a single, default equality comparison. If you want to implement multiple custom equality comparisons for the given type, you can have multiple classes implement IEqualityComparer<T>
and pass them to various LINQ methods.
For example, you can have a person class which implements IEquatable<Person>
:
public class Person : IEquatable<Person>
{
public Person(string name, int age)
{
Name = name;
Age = age;
}
public string Name { get; }
public int Age { get; }
public bool Equals(Person other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return string.Equals(Name, other.Name) && Age == other.Age;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((Person) obj);
}
public override int GetHashCode()
{
unchecked
{
return ((Name?.GetHashCode() ?? 0)*397) ^ Age;
}
}
public static bool operator ==(Person left, Person right)
{
return Equals(left, right);
}
public static bool operator !=(Person left, Person right)
{
return !Equals(left, right);
}
}
But now you want to implement a custom comparer, which only performs an equality check based on the persons name. You can implement a custom IEqualityComparer<Person>
:
public class ByNamePersonComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
return x.Name.Equals(y.Name, StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(Person obj)
{
return obj.GetHashCode();
}
}