为什么此代码会导致Stack Overflow C#?

时间:2019-12-01 20:58:55

标签: c# inheritance interface

下面的代码引发堆栈溢出。 B中的DoSomething调用了A中的DoSomething。A中的DoSomething应该调用其X的method的实现,但调用其派生类B的DoSomething。为什么?这是一个错误吗?

namespace Test
{
    class Program
    {
        static void Main()
        {
            B b = new B();
            b.DoSomething();
        }
    }
    interface X
    {
        void DoSomething();
    }
    class A : X
    {
        protected void DoSomething() => ((X)this).DoSomething(); // Making visible to derived classes
        void X.DoSomething() => Console.ReadKey();
    }
    interface Y : X
    {
        void DoSomethingElse();
    }
    class B : A, Y
    {
        public new void DoSomething() => base.DoSomething(); //Making publically visible
        public void DoSomethingElse() { }
    }
}

顺便说一句,此代码可以正常工作(如果我不继承Y中的X):

namespace Test
{
    class Program
    {
        static void Main()
        {
            B b = new B();
            b.DoSomething();
        }
    }
    interface X
    {
        void DoSomething();
    }
    class A : X
    {
        protected void DoSomething() => ((X)this).DoSomething(); // Making visible to derived classes
        void X.DoSomething() => Console.ReadKey();
    }
    interface Y
    {
        void DoSomethingElse();
    }
    class B : A, Y
    {
        public new void DoSomething() => base.DoSomething(); //Making publically visible
        public void DoSomethingElse() { }
    }
}

为什么在第一个示例中,B中的DoSomething试图实现X的DoSomething方法,该方法已经由A实现。如果不是bug,如何在不修改Y接口的情况下阻止B类这样做。因为我想在Y中反映出它继承了X。

1 个答案:

答案 0 :(得分:4)

发生这种情况是因为您的调用互相调用,所以此public new void DoSomething() => base.DoSomething();正在调用基本方法,即protected void DoSomething() => ((X)this).DoSomething();

this实例被强制转换为X类型,这显然是由AB实现的,((X)this).DoSomething();从{{ 1}}类,您将获得无限递归。

该行为的原因是,当在类型层次结构中多次明确地实现接口时,将使用派生最多的类型的实现。您可以查看language specification了解详情

您可以通过在类DoSomething()中使用B方法DoSomething()并像这样在public中删除其声明来避免这种情况

A