请考虑以下代码:
interface IFooable
{
void Foo();
}
class Blah : IFooable
{
public void Foo()
{
Console.WriteLine("Hi from 'Blah'");
}
}
class Bar : Blah, IFooable
{
public void Foo()
{
Console.WriteLine("Hi from 'Bar'");
}
}
编译此代码将在编译器中发出以下警告:
' Bar.Foo()'隐藏继承成员' Blah.Foo()'。如果想要隐藏,请使用new关键字。
但是' Foo'是一种接口方法实现,根据定义,它是IIRC,是虚拟的。如果您运行以下代码:
var fooableList = new List<IFooable>();
fooableList.Add(new Blah());
fooableList.Add(new Bar());
foreach (var fooable in fooableList)
{
fooable.Foo();
}
这肯定会像虚拟电话一样输出:
嗨,来自&#39; Blah&#39;
嗨,来自&#39; Bar&#39;
这是非常误导的,如果你继续并遵循编译器的警告建议标记Bar.Foo
为new
,它在程序的输出中根本没有任何影响。是的我知道我正在Bar
实施&#34;两次&#34; IFooable
但这仍然是合法代码,由此产生的警告是完全错误的。
我是否对接口和方法隐藏的工作方式产生了深刻的误解,或者这是一个极端情况编译器警告故障?
答案 0 :(得分:5)
你做的不仅仅是&#34;实施IFooable
两次&#34;。请考虑以下类似的代码:
interface IFooable
{
void Foo();
}
class Blah : IFooable
{
public void Foo()
{
Console.WriteLine("Hi from 'Blah'");
}
}
class Bar : Blah
{
public void Foo()
{
Console.WriteLine("Hi from 'Bar'");
}
}
您明确隐藏Blah
Foo
的实施。使Bar
也来自IFooable
并不会改变这一事实。要隐藏它,您需要在Blah
本身标记为虚拟。
请参阅MSDN。
答案 1 :(得分:1)
Blah类有一个Foo方法。酒吧班有一个Blah班。所以Blah类有一个Foo方法。这不应该两次实现接口。