可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Consider the following (LinqPad) example. ToString in class X is marked virtual. Why is the output here not equal to "Hi, I'm Y, Hi, I'm X" but instead the typename is printed? Of course marking ToString virtual is wrong, because it is defined in Object as virtual, I am just trying to understand what is happening here.
void Main() { Y y = new Y(); Console.WriteLine(y); } // Define other methods and classes here class X { public virtual String ToString() { return "Hi, I'm X"; } } class Y : X { public override String ToString() { return "Hi, I'm Y, " + base.ToString(); } }
回答1:
That's creating a new virtual method in X
called ToString()
which hides Object.ToString()
. So if you have:
Y y = new Y(); X x = y; Object o = y; Console.WriteLine(y.ToString()); // Shows "Hi, I'm Y, Hi, I'm X"; Console.WriteLine(x.ToString()); // Shows "Hi, I'm Y, Hi, I'm X"; Console.WriteLine(o.ToString()); // Calls object.ToString; shows just "Y"
Calling just
Console.WriteLine(y);
is equivalent to the final line, which is why the type name is printed.
Basically, your X.ToString
method should override the object.ToString()
method:
public override String ToString() { return "Hi, I'm X"; }
回答2:
By using virtual String ToString()
on class X
, you're "hiding" object.ToString
instead of overriding it.
When you call Console.WriteLine(y);
, it calls object.ToString()
. Since you didn't override this, your method never gets called.
That being said, the compiler will warn you:
Warning 1 'X.ToString()' hides inherited member 'object.ToString()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.