在C#中强制重写ToString()时,重写和new之间的区别
本文关键字:重写 new 之间 区别 ToString | 更新日期: 2023-09-27 18:27:28
我有这个经验代码:
interface I { string ToString(); }
class TestI : I {
public override string ToString() { return "Hello"; }
}
abstract class A1 { public override abstract string ToString(); }
class TestA1 : A1 {
public override string ToString() { return "world!"; }
}
abstract class A2 { public new abstract string ToString(); }
class TestA2 : A2 {
public override string ToString() { return "world!"; }
}
class Program {
static void Main(string[] args) {
TestI ti = new TestI();
I i = ti;
Console.WriteLine(ti); Console.WriteLine(i); //predictable writes "Hello"
TestA1 ta1 = new TestA1();
A1 a1 = ta1;
Console.WriteLine(ta1); Console.WriteLine(a1); //predictable writes "world!"
TestA2 ta2 = new TestA2();
A2 a2 = ta2;
Console.WriteLine(ta2); Console.WriteLine(a2); //writes "ConsoleApplication1.TestA2"
Console.WriteLine(ta2.ToString()); Console.WriteLine(a2.ToString()); //good
Console.ReadLine();
}
}
为什么new
关键字会破坏案例#3中的方法ToString()
?我知道方法Console.Write
有一个类似ToString(params object[])
的签名,它使用object.ToString()
实现。
在这种情况下,如何正确地强制覆盖ToString()
?我不想使用案例4。
与其试图强迫人们重写ToString
,为什么不在类上有一个调用抽象方法的基本实现呢。例如:
abstract class Base
{
protected abstract string GetMessage();
public sealed override string ToString()
{
return GetMessage();
}
}
class Derived : Base
{
protected override string GetMessage()
{
return "hello";
}
}
现在你没有试图欺骗编译器,任何使用你的类的人都会清楚地知道他们必须做什么。
案例Console.WriteLine(a2);Console.WriteLine方法中a2的编译时类型是一个对象,因为调用了获取对象的重载。由于您没有重写对象的ToString()方法,因此会调用对象中的默认ToString(。您没有在对象上重写ToString(),因为您通过"new"关键字(用于隐藏父类的方法)将方法隐藏在抽象类中,从而破坏了链。