You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让接口中的虚拟函数可直接从其实现类访问?

问题描述

我有如下接口:

public interface MyInterface
{
    int GetNumber();
    virtual int GetTwiceNumber()
        => 2 * GetNumber();
}

对应的实现类:

public class MyClass : MyInterface
{
    public int GetNumber()
        => 5;
}

目前我可以直接通过MyClass实例访问GetNumber,但必须将实例强制转换为MyInterface才能调用GetTwiceNumber:

MyClass myObject = new();
Console.WriteLine(((MyInterface)myObject).GetTwiceNumber());

输出:

10

我希望无需强制转换,就能直接从MyClass实例访问MyInterface中定义的GetTwiceNumber默认方法。如果直接复制方法代码到类里,复杂场景下不仅冗余,还容易出现接口方法更新但类中代码未同步的问题。

我曾尝试在类中添加同名方法:

public int GetTwiceNumber()
    => 2 * ((MyInterface)this).GetNumber();

但这样会覆盖接口的默认方法,导致调用时无限递归,最终抛出StackOverflowException。

请问在类不覆盖该接口默认方法的前提下,如何让类实例直接访问接口的默认方法?

解决方案

方法1:显式调用接口的默认实现

在类中添加一个公开方法,通过接口类型限定符明确调用接口的默认实现,避免自身覆盖导致的递归:

public class MyClass : MyInterface
{
    public int GetNumber() => 5;

    public int GetTwiceNumber() 
        => ((MyInterface)this).MyInterface.GetTwiceNumber();
}

这里MyInterface.GetTwiceNumber()指定调用接口定义的默认逻辑,不会与类的方法产生冲突。

方法2:使用扩展方法包装调用

如果不想修改MyClass的代码,可以通过扩展方法为实例添加直接调用的入口:

public static class MyClassExtensions
{
    public static int GetTwiceNumber(this MyClass instance)
    {
        return ((MyInterface)instance).GetTwiceNumber();
    }
}

使用时直接调用即可:

MyClass myObject = new();
Console.WriteLine(myObject.GetTwiceNumber()); // 输出10

方法3:结合显式接口实现与公开方法

若希望接口方法的实现完全依赖接口默认逻辑,同时类公开该方法,可以采用显式实现+包装的方式:

public class MyClass : MyInterface
{
    public int GetNumber() => 5;

    // 显式实现接口方法,确保使用接口默认逻辑
    int MyInterface.GetTwiceNumber() => MyInterface.GetTwiceNumber();

    // 公开方法提供直接访问入口
    public int GetTwiceNumber() => ((MyInterface)this).GetTwiceNumber();
}

内容的提问来源于stack exchange,提问作者Brendan Lynn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 13:50:21