编译器选择调用 IEquatable 的错误重载.等于
本文关键字:错误 重载 等于 选择 调用 IEquatable 编译器 | 更新日期: 2023-09-27 18:32:56
在性能敏感的程序中,我试图显式调用IEquatable<T>.Equals()
而不是Object.Equals
(以避免在我的情况下装箱)。 尽管我尽了最大的努力,编译器总是选择Object.Equals()
- 我不明白。 人为的示例类:
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;
}
}
同样人为的代码来演示问题:
// This calls IEquatable<Foo>
Foo f = new Foo();
f.Equals(f);
// This calls Object.Equals
IEquatable<Foo> i = new Foo();
i.Equals(i);
此代码的输出为:
IEquatable.Equals
Object.Equals
我读了乔恩·斯基特(Jon Skeet)关于重载的文章,但仍然不明白这里的问题。 所以我的问题是,如何在上面的变量i
上显式调用IEquatable<Foo>.Equals
?
选择第二个重载的原因与调用方的类型无关。相反,它与您传递给Equals
的参数类型有关。因此,即使您调用f.Equals(i)
,也会选择object.Equals
方法。原因很简单,编译器会寻找最合适的重载。由于IEquatable<Foo>
不一定是Foo
的,因为可能有另一种类型,比如说Bar
实现IEquatable<Foo>
,在这种情况下,选择Equals(Foo f)
重载是不对的(或不可能的)。
由于编译器不检查IEquatable<Foo>
的基础类型,因此如果要调用Equals(Foo)
重载,则需要显式强制转换为Foo
参数。