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

C#从重写方法调用基类方法:两种实例化方式的差异

两种m_canvas调用方式的差异说明

先明确给定的类定义:

public abstract class T_BaseClass
{
    public virtual void m_canvas()
    {
        Console.WriteLine("canvas method called from template.");            
    }
}

public class C_ChildT : T_BaseClass
{
    public override void m_canvas()
    {
        base.m_canvas();
        Console.WriteLine("canvas method called from child template.");
    }
}

两种调用方式的代码

方式一

C_ChildT mychildclass = new C_ChildT();
mychildclass.m_canvas();

方式二

T_BaseClass mychildclass1 = new C_ChildT();
mychildclass1.m_canvas();

核心差异分析

执行结果完全一致

两种方式调用后,控制台输出完全相同:

canvas method called from template.
canvas method called from child template.

这是因为C_ChildT重写了父类的virtual方法,无论变量声明类型是父类还是子类,CLR都会根据实例的实际类型(C_ChildT)执行重写后的方法。

变量类型与绑定机制的差异

  • 方式一中,变量mychildclass的声明类型和实际实例类型都是C_ChildT:编译器在编译阶段就能明确要调用的是C_ChildT的m_canvas,不过因为方法是虚方法,最终还是会通过运行时多态绑定确认(这里编译和运行时目标方法一致)。
  • 方式二中,变量mychildclass1的声明类型是父类T_BaseClass,实际实例类型是子类C_ChildT:编译阶段编译器只能识别父类的virtual方法,但运行时CLR会根据实例的真实类型找到子类重写的方法执行,这就是C#的运行时多态特性。

扩展性差异

如果后续给C_ChildT新增父类没有的方法(比如public void NewMethod()),方式一的变量可以直接调用mychildclass.NewMethod();而方式二的变量必须先强制转换为C_ChildT类型(((C_ChildT)mychildclass1).NewMethod())才能调用,因为编译器只认可变量声明类型(父类)的成员。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 16:01:10