In a performance sensitive program, I am attempting to explicitly call IEquatable<T>.Equals()
and not Object.Equals
(to avoid boxing in my case). Despite my best efforts, the compiler is always choosing Object.Equals()
instead - which I don't understand. A contrived example class:
class Foo : IEquatable<Foo>
{
public bool Equals(Foo f)
{
Console.WriteLine("IEquatable.Equals");
return true;
}
public override bool Equals(object f)
{
Console.WriteLine("Object.Equals");
return true;
}
}
Equally contrived code that demonstrates the problem:
// This calls IEquatable<Foo>
Foo f = new Foo();
f.Equals(f);
// This calls Object.Equals
IEquatable<Foo> i = new Foo();
i.Equals(i);
The output of this code is:
IEquatable.Equals
Object.Equals
I read Jon Skeet's article on overloading and came away still not understanding the problem here. So my question is, how do I explicitly call IEquatable<Foo>.Equals
on variable i
above?
The reason why the second overload chosen is irrelevant to the caller's type. Rather it's relevant to the type of argument you are passing to Equals
. So even if you call f.Equals(i)
, object.Equals
method will be chosen. The reason is simple, compiler looks for the most appropriate overload. Since the IEquatable<Foo>
doesn't have to be necessarily Foo
, cause there maybe another type let's say Bar
which implements IEquatable<Foo>
, in that case it wouldn't be right (or possible) to choose Equals(Foo f)
overload.
Since the compiler doesn't check the underlying type of IEquatable<Foo>
, you need to explicitly cast the parameter to Foo
if you want to call Equals(Foo)
overload.
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