为何new关键字被称隐藏基类方法?术语与调用行为的困惑
关于C#中new和override的“隐藏”与“重写”的疑惑解答
你提到的这个疑惑其实是对“隐藏(hiding)”这个术语的理解偏差——官方说的“隐藏”不是让基类方法彻底消失,而是改变了方法调用的绑定逻辑,和override的运行时多态形成鲜明对比。
先拆解一下两者的核心差异:
1. override:真正的运行时重写
当你用override修饰派生类的方法时,你是在替换基类虚方法的实现。这时候CLR会维护一个虚方法表(vtable),当通过基类引用调用方法时,会在运行时根据实例的实际类型去查找虚表,找到派生类的实现执行。
就像你代码里的情况:用override时,BaseClass bd = new DerivedClass(); bd.Method1();会输出派生类的内容,因为运行时识别到bd的实际类型是DerivedClass,调用的是重写后的方法。
2. new:编译时的方法隐藏
new关键字的作用是在派生类中创建一个和基类同名的全新方法——它和基类的方法没有任何重写关系,只是名字一样而已。这时候方法调用遵循静态绑定规则:编译器会根据变量的编译时声明类型来决定调用哪个方法。
回到你的例子:
- 当你用
new声明DerivedClass的Method1时,BaseClass bd = new DerivedClass();这个变量bd的编译时类型是BaseClass,所以编译器会绑定到BaseClass的Method1,运行时自然输出基类的内容; - 但如果换个写法:
这时候就会输出派生类的内容——这才是“隐藏”的真正含义:在派生类自身的类型上下文里,基类的同名方法被隐藏了,默认调用的是派生类的新方法。如果想在派生类实例里调用基类的方法,必须显式转换:DerivedClass dd = new DerivedClass(); dd.Method1();((BaseClass)dd).Method1(); // 输出Base - Method1
一句话总结两者的本质
override:动态绑定,运行时看实例的实际类型,是真正的“重写”;new:静态绑定,编译时看变量的声明类型,是“同名新方法隐藏基类方法”——基类方法并没有消失,只是在派生类类型里被同名方法覆盖了默认调用路径。
内容的提问来源于stack exchange,提问作者Sami
相关产品推荐
相关产品推荐

