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

C#为何调用该重载而非更具体的重载?(与重写相关)

问题

父类包含抽象方法abstract bool Filter(EntityComponent entity),但子类中我更倾向于实现bool Filter(BaseComponent entity)(EntityComponent是BaseComponent的子类,且其他地方也会调用后者)。为避免栈溢出,我给参数加了强制转换:

protected override bool Filter(EntityComponent entity) => Filter((BaseComponent)entity);

protected bool Filter(BaseComponent entity)
{
    return
        (AllowBeavers && entity.GetComponentFast<BeaverSpec>())
        || (AllowBots && entity.GetComponentFast<BotSpec>());
}

但Visual Studio提示可以移除强制转换,且移除后仍能调用正确的方法。我很困惑:为什么编译器会选择Filter(BaseComponent)而非更具体的重载?移除转换后为什么不会发生递归?

解答

这背后是C#的重载解析规则在起作用:

  • 不会递归的核心原因:重载解析优先匹配“非重写方法”
    当你在重写的Filter(EntityComponent)方法里直接写Filter(entity)时,编译器首先会在当前类的成员中查找匹配的方法。当前类里有两个候选:

    • 重写的Filter(EntityComponent)(父类抽象方法的实现)
    • 你自定义的Filter(BaseComponent)
      C#规定,在当前类中,非重写的方法优先级高于重写的父类方法——重写方法本质上属于父类的方法签名,当前类自己定义的重载会被优先考虑。因此编译器会选择你写的Filter(BaseComponent),而非调用自身导致递归。
  • 移除强制转换仍能匹配的原因
    EntityComponent是BaseComponent的子类,entity可以隐式转换为BaseComponent类型。当编译器处理Filter(entity)时,即便存在参数类型更精确的Filter(EntityComponent)重载,但因为它是重写的父类方法,优先级低于当前类自定义的Filter(BaseComponent),所以会自动完成隐式转换,调用后者。

简言之:编译器在当前类中查找方法时,自定义的重载比重写父类的方法优先级更高,因此既不会触发递归,也不需要手动强制转换。

内容的提问来源于stack exchange,提问作者Luke Vo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 00:37:40