如何调用默认方法而不是具体实现

Bas*_*ili 10 c# c#-8.0 default-interface-member

为什么默认接口方法的行为在 C# 8 中发生了变化?过去的以下代码(当默认接口方法未发布时):

interface IDefaultInterfaceMethod
{
    // By default, this method will be virtual, and the virtual keyword can be here used!
    virtual void DefaultMethod()
    {
        Console.WriteLine("I am a default method in the interface!");
    }

}

interface IOverrideDefaultInterfaceMethod : IDefaultInterfaceMethod
{
    void IDefaultInterfaceMethod.DefaultMethod()
    {
        Console.WriteLine("I am an overridden default method!");
    }
}

class AnyClass : IDefaultInterfaceMethod, IOverrideDefaultInterfaceMethod
{
}

class Program
{
    static void Main()
    {
        IDefaultInterfaceMethod anyClass = new AnyClass();
        anyClass.DefaultMethod();

        IOverrideDefaultInterfaceMethod anyClassOverridden = new AnyClass();
        anyClassOverridden.DefaultMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

有以下输出:

控制台输出:

我是界面中的默认方法!
我是一个被覆盖的默认方法!

但是对于 C# 8 的最后一个版本,上面的代码会产生以下输出:

控制台输出:

我是一个被覆盖的默认方法!
我是一个被覆盖的默认方法!

任何人都可以向我解释为什么这种行为会改变?

笔记:

IDefaultInterfaceMethod anyClass = new AnyClass(); anyClass.DefaultMethod();

((IDefaultInterfaceMethod) anyClass).DefaultMethod(); // STILL the same problem!??
Run Code Online (Sandbox Code Playgroud)

Pan*_*vos 6

我怀疑一个更好的问题是:

如何调用默认方法而不是具体实现?

该功能是计划中的,但在 2019 年 4 月从 C# 8 中删除,因为有效的实现需要运行时的支持。这在发布之前无法及时添加。该功能必须同时适用于 C# 和 VB.NET - F# 无论如何都不喜欢接口。

如果运行时 BM 不存在,则将调用 AM()。对于 base() 和接口,运行时不支持,因此调用将抛出异常。我们想在运行时添加对此的支持,但发布此版本的成本太高了。

我们有一些解决方法,但它们没有我们想要的行为,也不是首选的代码生成器。

我们对 C# 的实现在某种程度上是可行的,虽然不完全是我们想要的,但是 VB 实现会困难得多。此外,VB 的实现将要求接口实现方法是公共 API 表面。

它将通过base()类似于类工作方式的调用来工作。复制提案示例:

interface I1
{ 
    void M(int) { }
}

interface I2
{
    void M(short) { }
}

interface I3
{
    override void I1.M(int) { }
}

interface I4 : I3
{
    void M2()
    {
        base(I3).M(0) // What does this do?
    }
}
Run Code Online (Sandbox Code Playgroud)