简体   繁体   中英

Compiler picking wrong overload calling IEquatable<T>.Equals

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM