I have a class Person, it implements Equals() method from IEquatable<Person> (also overrides Object.Equals method, lets ignore the GetHashcode() method for now)
class Person : IEquatable<Person>
{
public string Name { get; set; }
public bool Equals(Person other)
{
return this.Name == other.Name;
}
public override bool Equals(object obj)
{
var person = obj as Person;
return person != null && person.Name == Name;
}
}
Ok, lets start:
Person p1 = new Person() { Name = "a" };
Person p2 = new Person() { Name = "a" };
List<Person> lst1 = new List<Person>() { p1 };
List<Person> lst2 = new List<Person>() { p2 };
Lets talk about this line :
bool b = lst1.SequenceEqual(lst2, EqualityComparer<Person>.Default);
I have a problem understanding this part :
EqualityComparer<Person>.Default
I’ve heard that EqualityComparer<Person>.Default will check if the class is implementing IEquatable – it will take the Equals(Person other) Method and not the Equals(object obj). it has the advantage of avoiding boxing

but
the Equals(Person other) will run with or withOUT EqualityComparer<Person>.Default
(because it’s implementing IEquatable)
So what Boxing are we talking about ? there isn’t !
The only time that Equals(object obj) will run is when :
bool b = lst1.SequenceEqual(lst2,EqualityComparer<Object>.Default);
But I’m a programmer! I’ll never Send an object when its actually a Person!
What am I missing? I’m having trouble understanding the benefit here of EqualityComparer<Object>.Default. Can someone please give me an example to prove me I’m wrong ?
If you pass in
nullas the second parameter or if you don’t pass in a second argument at all (which is basically the same), the implementation of SequenceEquals will callEqualityComparer<T>.Defaultitself (decompileEnumerableto see this). That explains why you don’t see a difference whether you provideEqualityComparer<T>.Defaultor not.So in the end the second parameter only makes sense if you want to use an equality comparer other than
EqualityComparer<T>.Default.