C#中override与new关键字重写ToString()的区别疑问
搞懂C#中override和new关键字的核心区别
嘿,作为曾经也被这俩关键字绕晕的C#新手,我太懂你的困惑了!你当前的代码输出确实一样,但这只是因为你直接用子类实例调用的——咱们换个场景,立马就能看出本质区别!
先把你的代码补全并加上关键测试场景:
class A { public new string ToString() { return "With New Keyword"; } } class B { public override string ToString() { return "With Override Keyword"; } } class Program { static void Main(string[] args) { // 直接用子类引用调用,输出看起来一样 A a = new A(); B b = new B(); Console.WriteLine(a.ToString()); // 输出: With New Keyword Console.WriteLine(b.ToString()); // 输出: With Override Keyword // 重点看向上转型后的调用!这才是区别所在 object objA = new A(); object objB = new B(); Console.WriteLine(objA.ToString()); // 输出: 你的命名空间.A(object基类的ToString实现) Console.WriteLine(objB.ToString()); // 输出: With Override Keyword } }
两者的本质差异
override:真正的「重写」
当你用override时,你是在彻底替换基类中标记为virtual/abstract的方法实现。基类会“记住”子类有新的实现,所以不管你是用子类类型的引用,还是把实例向上转成基类类型的引用,调用方法时都会找到子类的实现。就像例子里的B类,哪怕转成object类型,调用ToString()还是会用B自己的实现。new:只是「隐藏」基类方法
new关键字的作用是在子类中隐藏基类的同名方法,注意是“隐藏”不是“替换”。它只在你用子类类型的引用调用时生效;如果把子类实例向上转成基类类型(比如object),调用方法时会直接跳过子类的实现,用基类原本的版本。就像A类,转成object后调用ToString(),用的是object自带的默认实现,而不是A里写的那个。
再举个更直观的自定义基类例子
class BaseGreeting { public virtual void SayHi() => Console.WriteLine("👋 来自基类的问候"); } class OverrideGreeting : BaseGreeting { public override void SayHi() => Console.WriteLine("👋 来自Override的问候"); } class NewGreeting : BaseGreeting { public new void SayHi() => Console.WriteLine("👋 来自New的问候"); } // 测试代码 BaseGreeting overrideObj = new OverrideGreeting(); BaseGreeting newObj = new NewGreeting(); overrideObj.SayHi(); // 输出: 👋 来自Override的问候 newObj.SayHi(); // 输出: 👋 来自基类的问候
总结一下
- 如果你想让所有指向子类实例的引用(不管是子类还是基类类型)都使用新的方法实现,用
override(前提是基类方法是virtual/abstract的)。 - 如果你只是想在子类里定义一个同名的独立方法,和基类方法划清界限,用
new——这时候基类方法不会被替换,只是在子类类型的引用下被“藏”起来了。
内容的提问来源于stack exchange,提问作者Pravin Tukadiya
相关产品推荐
相关产品推荐

