覆盖接口实现时错误的编译器警告?

时间:2014-09-08 22:04:53

标签: c#

请考虑以下代码:

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.Foonew,它在程序的输出中根本没有任何影响。是的我知道我正在Bar实施&#34;两次&#34; IFooable但这仍然是合法代码,由此产生的警告是完全错误的。

我是否对接口和方法隐藏的工作方式产生了深刻的误解,或者这是一个极端情况编译器警告故障?

2 个答案:

答案 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方法。这不应该两次实现接口。