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 ?
That you can pass in IEqualityComparer<object>.Default
is an effect of generic contravariance, added in .NET 4.
Essentially, an IEqualityComparer<BaseType>
can be used whenever an IEqualityComparer<DerivedType>
is required, where DerivedType : BaseType
. Since Person
derives from Object
, this means that an IEqualityComparer<Object>
can be used wherever an IEqualityComparer<Person>
is required.
If you pass in null
as 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 call EqualityComparer<T>.Default
itself (decompile Enumerable
to see this). That explains why you don't see a difference whether you provide EqualityComparer<T>.Default
or not.
So in the end the second parameter only makes sense if you want to use an equality comparer other than EqualityComparer<T>.Default
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With