.NET 5中多级继承的运行原理是什么?含方法重写、隐藏场景疑问
.NET 5 多级继承场景3底层运行逻辑解析
首先明确C#中两个核心关键字的语义差异:
override:沿虚方法继承链修改对应虚方法的实现,属于对父类已有虚方法的扩展,不会改变虚方法的继承链结构new:仅在当前类层级隐藏父类的同名方法,相当于定义了一个和父类同名但无关联的全新方法,如果搭配virtual使用,只会以当前类为起点开启一条新的虚方法继承链,不会影响父类原有的虚方法链
场景3代码还原
你提到的场景3可简化为如下代码结构:
public class ClassASuper { public virtual void Display() { Console.WriteLine("ClassASuper.Display"); } } public class ClassA : ClassASuper { // 用new关键字隐藏父类的Display,同时新增virtual修饰,开启新的虚方法链 public new virtual void Display() { Console.WriteLine("ClassA.Display"); } } public class ClassB : ClassA { // 此处override重写的是ClassA新增的虚方法Display,和ClassASuper的Display无关联 public override void Display() { Console.WriteLine("ClassB.Display"); } }
底层运行逻辑
.NET运行时的方法调用依赖每个类型的**方法表(Method Table)**结构:
- 每个类的方法表会继承父类所有虚方法的槽位,
override关键字只会替换对应槽位的方法指针,不会新增槽位 - 当ClassA用
new virtual定义Display方法时,不会修改从ClassASuper继承来的Display方法槽位的指针,而是在ClassA的方法表中新增一个独立的虚方法槽位,专门存放新的Display方法的指针 - ClassB中
override的Display,只会替换从ClassA继承来的、那个新增的Display方法槽位的指针,不会修改最上层ClassASuper对应的原Display槽位的指针
这也是为什么会出现看似矛盾的运行结果:
- 如果用
ClassASuper obj = new ClassB(); obj.Display();,调用时会从ClassASuper对应的虚方法槽位找实现,这条链上ClassA和ClassB都没有重写该槽位的方法,最终执行的是ClassASuper的实现 - 如果用
ClassA obj = new ClassB(); obj.Display();,调用时会从ClassA新增的Display虚方法槽位找实现,该槽位已经被ClassB的override替换,最终执行的是ClassB的实现 - 如果用
ClassB obj = new ClassB(); obj.Display();,执行逻辑和上面一致,结果为ClassB的实现
内容的提问来源于stack exchange,提问作者Ritesh Kumar
相关产品推荐
相关产品推荐

