如何在派生类重新实现接口时调用基接口实现?

时间:2014-04-30 16:24:43

标签: c# .net inheritance interface

因此,出于某种原因,我正在测试C#和.NET VM的限制。我遇到了一些令人困惑的行为。

采用这些类和接口:

public interface ITest
{
    void Test();
    void Test2();
}
public abstract class Base : ITest
{
    void ITest.Test()
    {
        Console.WriteLine("base");
    }
    public void Test2()
    {
        Console.WriteLine("base2");
    }
    public void Test3()
    {
        Console.WriteLine("base3");
    }
}
public class Impl : Base, ITest
{
    void ITest.Test()
    {
        Console.WriteLine("impl");
    }
    void ITest.Test2()
    {
        Console.WriteLine("impl2");
    }
    public void Test3()
    {
        Console.WriteLine("impl3");
    }
}

然后像这样使用它们:

        var i = new Impl();
        var b = (Base)i;
        var itest1 = (ITest)i;
        var itest2 = (ITest)b;
        itest1.Test();
        itest2.Test();
        itest1.Test2();
        itest2.Test2();
        i.Test2();
        b.Test2();
        i.Test3(); //for reference, a standard non-virtual method outside of an interface
        b.Test3();

我希望输出看起来像这样:

impl
base
impl2
base2
impl2
base2
impl3
base3

但当然,事情不可能那么简单。所以,实际输出是这样的:

impl
impl
impl2
impl2
base2
base2
impl3
base3

除了这种疯狂的奇怪行为之外,是否可以访问Base.Test()实现?

2 个答案:

答案 0 :(得分:2)

也许你应该检查一下为什么你会发现你变得奇怪的结果。对我来说,看起来你得到了你所实现的。

由于没有Base.Test,无法获得Base.Test。您需要通过界面明确地访问它,然后它不再是Base,而是Impl,因为底层真实对象不是Base类型。

答案 1 :(得分:0)

Base明确实施ITest.Test()。它是一种实施方式,但它是"私有" 实施,只能通过ITest界面访问。

最重要的是,Impl 重新实施 ITest.Test(),所以当你尝试itest2.Test()时,你会指出这个重新实现

这里的两个关键点是:

  1. 没有公开Base.Test()
  2. 您通过ITest.Test() 重新实施,杀死了Base Impl实施{{1}}实施的所有可能性。
  3. 重新实施,重新实施,重新实施。

    我建议稍微重命名一下这个问题:当派生类显式重新实现界面时,如何调用基接口显式实现?因为那是你要问的...... < / p>