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

C# 8 默认接口方法:多接口实现调用结果存疑

为什么调用IPlayer.Attack(5)会输出55?

这问题我刚看到的时候也琢磨了下,其实核心是C#里显式接口实现和接口方法隐藏的规则在起作用,我给你一步步拆解:

首先先把你的代码贴出来方便对照:

public interface IPlayer { int Attack(int amount); }
public interface IPowerPlayer: IPlayer { int IPlayer.Attack(int amount) { return amount + 50; } }
public interface ILimitedPlayer: IPlayer { new int Attack(int amount) { return amount + 10; } }
public class Player : IPowerPlayer, ILimitedPlayer { }

执行代码:

IPlayer player = new Player(); 
Console.WriteLine(player.Attack(5)); // 输出55

关键知识点1:显式接口实现的特殊性

IPowerPlayer里的int IPlayer.Attack(int amount)是显式接口实现——这种写法的意思是:我实现的是IPlayer接口的Attack方法,而且这个方法只能通过IPlayer类型的引用才能调用,不属于IPowerPlayer自己的方法(哪怕IPowerPlayer继承自IPlayer)。

关键知识点2:new关键字是“隐藏”而非“重写”

ILimitedPlayer里的new int Attack(int amount)用了new关键字,它的作用是隐藏继承自IPlayer的Attack方法,而不是重写。也就是说,这个Attack是ILimitedPlayer自己独有的方法,和IPlayer的Attack是两个完全不同的方法——只有当你用ILimitedPlayer类型的引用调用时,才会触发这个方法。

为什么输出55?

当你把Player实例赋值给IPlayer类型的变量时,C#会去寻找这个类中直接实现IPlayer.Attack的方法。而你的代码里,只有IPowerPlayer用显式实现的方式完成了IPlayer.Attack的实现,ILimitedPlayer的Attack是自己的方法,和IPlayer的Attack没关系。

所以调用player.Attack(5)时,实际执行的是IPowerPlayer里显式实现的IPlayer.Attack,也就是5 + 50 = 55。

额外验证:换个类型调用试试

如果我们换不同的接口类型调用,结果就不一样了:

// 用ILimitedPlayer类型调用,会触发它自己的Attack方法
ILimitedPlayer limited = new Player();
Console.WriteLine(limited.Attack(5)); // 输出15

// 用IPowerPlayer类型调用,因为它继承IPlayer,实际还是调用显式实现的IPlayer.Attack
IPowerPlayer power = new Player();
Console.WriteLine(power.Attack(5)); // 输出55

这样是不是就清晰多啦?

内容的提问来源于stack exchange,提问作者Bassam Alugili

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:13:10