Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当派生类重新实现接口时,如何调用基接口实现?_C#_.net_Inheritance_Interface - Fatal编程技术网

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

C# 当派生类重新实现接口时,如何调用基接口实现?,c#,.net,inheritance,interface,C#,.net,Inheritance,Interface,因此,出于这样或那样的原因,我正在测试C#和.NET虚拟机的限制。我遇到了一些令人困惑的行为 以这些类和接口为例: public interface ITest { void Test(); void Test2(); } public abstract class Base : ITest { void ITest.Test() { Console.WriteLine("base"); } public void Test2()

因此,出于这样或那样的原因,我正在测试C#和.NET虚拟机的限制。我遇到了一些令人困惑的行为

以这些类和接口为例:

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()

这里的两个要点是:

  • 没有公共的
    Base.Test()
  • 通过在
    Impl
    上重新实现
    it,您消除了在
    Base
    上访问
    ITest.Test()
    实现的所有可能性
  • 再实施,再实施,再实施。
    我可以建议稍微重命名一下这个问题:当派生类显式重新实现接口时,如何调用基接口显式实现?因为这就是您要问的…

    但是如果您将
    Test3
    方法同时添加到基和Impl,但不添加到接口,那么您将看到base3,我所期望的impl3行为它似乎总是将接口实现视为虚拟的,但它们没有标记为虚拟的。如果一切都是虚拟的,我会期待这种行为。这里的关键是您在Impl中重新实现了接口。所以它将使用其本机实现,而不是从Base继承的实现。@NickZimmerman但是如何使用呢?它被强制转换到一个基,那么为什么它不使用基的实现呢?请注意,当你不强制转换到ITest时,你得到的是基的实现,因为它通过继承链,继承了继承的版本。按照我所能看到的做它应该做的。铸造不是转化。确切地说,铸造不是转化。此外,我建议稍微重命名这个问题:当派生类显式重新实现接口时,如何调用基接口显式实现?