C# 8 基本接口的默认方法调用解决方法

Jan*_*kke 9 c# reflection .net-core c#-8.0

根据https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods 可以使用以下语法显式调用接口基础实现。

base(IInterfaceType).Method();
Run Code Online (Sandbox Code Playgroud)

但这似乎还没有实施。

是否有解决方法(例如反射)来实现这一目标?


示例代码来说明问题

interface IA
{
    void M()
    {
        Console.WriteLine("IA.M");
    }
}

interface IB : IA
{
    void IA.M()
    {
        Console.WriteLine("IB.M");
    }
}

interface IC : IA
{
    void IA.M()
    {
        Console.WriteLine("IC.M");
    }
}

class D : IA, IB, IC
{
    public void M()
    {
        // base(IB).M(); Is not yet supported apparently
        ((IB)this).M(); // Throws stack overflow
    }
}

class Program
{
    static void Main(string[] args)
    {
        D d = new D();
        d.M();
    }
}
Run Code Online (Sandbox Code Playgroud)

Pan*_*vos 7

问题中的链接指向从 Github 中的提案文档复制的提案版本

该功能于2019 年 4 月删减

结论

削减 C# 8 的 base() 语法。我们打算在下一个主要版本中恢复它。

设计会议文档解释说,如果没有运行时支持(无法及时提供),该实现最多只能用于 C#,但不能用于 VB.NET。

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

我们有一些解决方法,但它们没有我们想要的行为,也不是首选的代码生成器。我们对 C# 的实现在某种程度上是可行的,虽然不完全是我们想要的,但是 VB 实现会困难得多。此外,VB 的实现将要求接口实现方法是公共 API 表面。

对于无限递归,这个

public void M()
{
    ((IB)this).M(); // Throws stack overflow
}
Run Code Online (Sandbox Code Playgroud)

这本质上

public void M()
{
    M(); // Throws stack overflow
}
Run Code Online (Sandbox Code Playgroud)

默认接口成员的调用方式与通过接口显式实现的接口方法相同。此外,您要求在 上调用该方法this,而不是base