当派生类重新实现接口时,如何调用基本接口实现

本文关键字:实现 接口 何调用 调用 派生 新实现 | 更新日期: 2023-09-27 18:00:54

因此,出于这样或那样的原因,我正在测试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((实现吗?

当派生类重新实现接口时,如何调用基本接口实现

也许你应该检查一下为什么你发现结果很奇怪。在我看来,你似乎得到了你所实现的。

因为没有Base.Test,所以没有办法得到Base.Test。您需要通过接口显式访问它,然后它不再是Base,而是Impl,因为底层的实际对象不是Base类型。

Base显式实现ITest.Test()。这是一个实现,但它是一个"私有">实现,只能通过ITest接口访问。

最重要的是,Impl正在重新实现ITest.Test(),因此当您尝试itest2.Test()时,您将在稍后再次实现

这里的2个关键点是:

  1. 没有公共Base.Test()
  2. 您通过Impl上重新实现,扼杀了在Base上访问ITest.Test()实现的所有可能性

重新实施,重新实施,再次实施

我可以建议稍微重命名这个问题吗:当派生类显式重新实现接口时,如何调用基本接口显式实现因为这就是你要问的。。。