10

为什么在 C# 8 中更改了默认接口方法的行为?过去如下代码(默认接口方法demo时未发布):

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

具有以下输出:

控制台输出:

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

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

控制台输出:

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

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

笔记:

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

((IDefaultInterfaceMethod) anyClass).DefaultMethod(); // STILL the same problem!??
4

1 回答 1

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?
    }
}
于 2020-01-15T09:42:18.737 回答