方法覆盖和可选参数 [英] Method Overriding and Optional Parameters
问题描述
有人会关心解释此代码如何产生以下输出吗?
Would someone care to explain how this code produces the folowing output?
using System;
namespace ConsoleApplication1
{
class Test
{
public override string ToString() { return "ToString override"; }
public string ToString(string optional = "")
{ return String.Format("ToString with optional parameter {0}", optional); }
}
class Test2
{
public new string ToString() { return "ToString new"; }
public string ToString(string optional = "")
{ return String.Format("ToString with optional parameter {0}", optional); }
}
class Program
{
static void Main(string[] args)
{
Test one = new Test();
Test2 two = new Test2();
Console.WriteLine(one);
Console.WriteLine(one.ToString());
Console.WriteLine(one.ToString("foo"));
Console.WriteLine("--");
Console.WriteLine(two);
Console.WriteLine(two.ToString());
Console.WriteLine(two.ToString("bar"));
Console.ReadKey();
}
}
}
ToString覆盖
ToString override
带可选参数的ToString
ToString with optional parameter
带可选参数foo的ToString
ToString with optional parameter foo
-
ConsoleApplication1.Test2
ConsoleApplication1.Test2
ToString new
ToString new
带可选参数栏的ToString
ToString with optional parameter bar
推荐答案
好的,作为这是一个普遍的兴趣,这是一个快速版本:
Okay, as there's general interest, here's a quick version:
Console.WriteLine(一个)
这将使用 WriteLine(object)
重载,它将依次执行 object.ToString()
virtual方法,在一个
中重写 - 因此输出 ToString覆盖
This will use the WriteLine(object)
overload, which will in turn execute the object.ToString()
virtual method, overridden in One
- hence the output of ToString override
Console.WriteLine(one.ToString())
这将查看 One
并查看哪些方法具有新声明的方法 - 折扣优先权。只有一种适用的方法 - 带有可选参数的方法。因此,使用默认值执行,导致输出 ToString,带有可选参数
。
This will look at One
and see which methods have newly declared methods - discounting overrides. There's exactly one such method which is applicable - the one with the optional parameter. So that gets executed, using the default value, leading to output of ToString with optional parameter
.
Console.WriteLine(one.ToString(foo))
再次相同,但这次编译器不需要使用默认值,因此带有可选参数foo的ToString
Same again, but this time the compiler doesn't need to use the default value, hence ToString with optional parameter foo
Console.WriteLine(两个)
同样,这将从 WriteLine(object)<调用虚拟
object.ToString()
方法/ code>。该方法尚未被覆盖,因此使用返回该类型名称的默认实现,导致输出 ConsoleApplication1.Test2
。
Again, this will call the virtual object.ToString()
method from WriteLine(object)
. The method hasn't been overridden, so the default implementation returning the name of the type is used, leading to output of ConsoleApplication1.Test2
.
Console.WriteLine(two.ToString())
编译器查看<$中声明的所有方法c $ c>两个哪个不覆盖虚拟方法。在这种情况下,有两种这样的方法 - 无参数方法和带可选参数的方法。包含无参数的一个因为它是 new 而不是覆盖基类方法。
The compiler looks at all the method declared in Two
which aren't overriding virtual methods. In this case, there are two such methods - the parameterless one and the one with the optional parameter. The parameterless one is included because it's new rather than overriding a base class method.
无参数方法被认为是更好的候选者,因为编译器更喜欢调用一个不需要填写任何可选参数的方法。因此输出 ToString new
The parameterless method is deemed a "better" candidate because the compiler prefers to call a method which doesn't need any optional parameters filling in. Hence the output is ToString new
Console.WriteLine(two.ToString(bar))
再次,编译器查看<$ c中声明的所有方法$ c>两个哪个不覆盖虚拟方法。在这种情况下,有两种这样的方法 - 但是无参数的方法不适用,只留下带有可选参数的方法。编译器不需要在这里使用可选参数的默认值,因为它无论如何都有一个参数...所以输出是带有可选参数栏的ToString
Again, the compiler looks at all the method declared in Two
which aren't overriding virtual methods. In this case, there are two such methods - but the parameterless one isn't applicable, leaving just the one with the optional parameter. The compiler doesn't need to use the default value of the optional parameter here, as it's got an argument anyway... so the output is ToString with optional parameter bar
关于这方面的更多内容,请阅读C#语言规范 - 或者对于中途宿舍,请参阅我的关于重载的文章。
For much more on this, read the C# language specification - or for a half-way house, see my article on overloading.
这篇关于方法覆盖和可选参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!