如何在继承的函数中重新定义在主体接口中定义的函数而不覆盖?

Mur*_*ren 21 c# inheritance overriding interface default-interface-member

有人可以解释同一类上的相同函数的行为有何不同吗?

using System;

public class HelloWorld
{
    public static void Main(string[] args)
    {
        MyUpperScript mAsdfScript = new MyUpperScript();
        IInterface mAsdfInterface = mAsdfScript;
        mAsdfScript.Foo();
        mAsdfInterface.Foo();
    }
}

public class MyUpperScript : MyScript
{
    public void Foo()
    {
        Console.WriteLine("Upper Script");
    }
}
public class MyScript : IInterface
{

}

public interface IInterface
{
    public void Foo()
    {
        Console.WriteLine("Interface");
    }
}

Run Code Online (Sandbox Code Playgroud)

我期望它在 Foo() 调用上都写“Upper Script”

请注意,如果我也从接口派生第二个类,它会按照我期望的方式工作 - 都打印“Upper Script”:

// now deriving for the interface too:
public class MyUpperScript : MyScript, IInterface
{
    public void Foo()
    {
        Console.WriteLine("Upper Script");
    }
}
Run Code Online (Sandbox Code Playgroud)

Tom*_*han 6

我怀疑这是因为

类不会从其接口继承成员

(从这里开始),意味着MyScript实际上没有覆盖的Foo方法。MyUpperScript当(现在我真的在这里猜测......!)您将变量重新转换为接口类型时,虚拟方法查找不再知道要查找FooMyUpperScript因此会退回到默认实现。

不过,对我来说仍然很奇怪,它并没有间接推断MyUpperScript实现IInterface- 但这可能只是我关于其工作方式的心智模型一直是错误的,并且没有机会产生任何实际的影响,直到你有默认的接口成员。(在这些之前,隐式实现的接口的所有成员也将从显式实现的超类继承。)就我个人而言,我认为如果修复了这个问题,那么该语言可能会更有意义,以便这两个原因的行为就像您指定了接口一样明确地(如在你的尾注中),但我无法找到任何文本来向我表明这是否是一个有意识的决定,以及如果它确实是有意识的,其理由是什么。

如果您尝试直接使用它MyScript(如下所示),您应该会收到编译器错误:

MyScript myScript = new MyScript();
myScript.Foo(); // compiler error here
Run Code Online (Sandbox Code Playgroud)