You need to enable JavaScript to run this app. C#中编译器如何处理方法隐藏?父类引用调用隐藏方法的原理疑问
优惠活动
大模型
产品
解决方案
定价
更多

C#中编译器如何处理方法隐藏?父类引用调用隐藏方法的原理疑问

C# 中父类引用调用隐藏方法的底层逻辑

这个问题本质是C#对override重写和new隐藏两种语法的语义设计差异,和运行时能否识别对象实际类型无关,核心区别在于两者对虚方法表(vtable)的操作逻辑完全不同。

核心概念差异

  • 重写(override+virtual):是对基类虚方法表中同一槽位的实现替换。基类定义virtual方法时会在vtable中预留固定槽位,子类使用override关键字时,会直接替换子类vtable中该槽位的实现逻辑。运行时调用虚方法时,会直接取实际对象类型vtable对应槽位的实现,所以父类引用也能调用到子类的重写方法。
  • 隐藏(new):是在子类中声明完全独立的全新同名方法,和基类的同名方法没有继承关联,也不会修改基类方法在vtable中的原有槽位,只会在子类vtable中新增独立的槽位存储这个新方法的实现。

为什么父类引用调用不到子类的隐藏方法

父类引用的编译时类型决定了编译器能识别的vtable槽位范围:当你通过父类类型引用调用方法时,编译器只会根据父类的方法定义去匹配对应的vtable槽位,子类用new声明的隐藏方法不在父类的方法定义范围内,运行时自然找不到对应的实现,只会调用父类的原有方法。

代码示例验证

class BaseClass
{
    public virtual void OverrideMethod()
    {
        Console.WriteLine("基类虚方法");
    }

    public void HideMethod()
    {
        Console.WriteLine("基类普通方法");
    }
}

class DerivedClass : BaseClass
{
    // 重写:替换同一vtable槽位的实现
    public override void OverrideMethod()
    {
        Console.WriteLine("子类重写的方法");
    }

    // 隐藏:新增独立的同名方法
    public new void HideMethod()
    {
        Console.WriteLine("子类隐藏的方法");
    }
}

// 运行测试
public static void Main()
{
    BaseClass obj = new DerivedClass();
    obj.OverrideMethod(); // 输出:子类重写的方法
    obj.HideMethod(); // 输出:基类普通方法

    // 强转为子类类型后才能调用到隐藏方法
    ((DerivedClass)obj).HideMethod(); // 输出:子类隐藏的方法
}

内容的提问来源于stack exchange,提问作者Samin Sadman Shad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 04:54:11