It should be the same, but it is not guaranteed, because it depends on implementation details of the type T
.
Explanation:
Without a constraint to T
, o1.Equals(o2) will call Object.Equals
, even if T
implements IEquatable<T>
.
EqualityComparer<T>.Default
however, will use Object.Equals
only, if T
doesn’t implement IEquatable<T>
. If it does implement that interface, it uses IEquatable<T>.Equals
.
As long as T
‘s implementation of Object.Equals
just calls IEquatable<T>.Equals
the result is the same. But in the following example, the result is not the same:
public class MyObject : IEquatable<MyObject>
{
public int ID {get;set;}
public string Name {get;set;}
public override bool Equals(object o)
{
var other = o as MyObject;
return other == null ? false : other.ID == ID;
}
public bool Equals(MyObject o)
{
return o.Name == Name;
}
}
Now, it doesn’t make any sense to implement a class like this. But you will have the same problem, if the implementer of MyObject
simply forgot to override Object.Equals
.
Conclusion:
Using EqualityComparer<T>.Default
is a good way to go, because you don’t need to support buggy objects!