我注意到使用具有可选参数的虚方法时。当您重写此方法并为可选参数使用不同的默认值时,它将使用原始方法。这对我来说有点奇怪。
static void Main(string[] args)
{
List<Piece> Pieces = new List<Piece>();
Pieces.Add(new Piece());
Pieces.Add(new Pawn());
foreach(var v in Pieces)
{
Console.WriteLine(v.getPos());
}
Console.ReadKey();
}
class Piece
{
public virtual long getPos(bool enPassant = false)
{
if (enPassant)
return 2;
return 1;
}
}
class Pawn:Piece
{
public override long getPos(bool enPassant = true)
{
if (enPassant)
return 3;
return 4;
}
}
最初我希望输出为
1
3
但它返回
1
4
这意味着它们都是假的。我甚至可以将参数重命名为不同的名称,并在方法体中使用不同的名称,它仍然表现相同。这告诉我默认参数值不能被覆盖,因为这是合同的一部分?显然,如果我将项目转换为Pawn对象,然后调用GetPos(),则返回3而不是4。
我只是觉得这很有意思,因为我预计它的表现会有所不同。我只是想知道我是否遗漏了任何东西,使我的工作按照我原先的意图。
答案 0 :(得分:4)
可选参数在编译时在调用现场解析 。
这意味着v.GetPos()
实际上已编译为v.GetPos(false)
,因为v
已键入Piece
。该呼叫是虚拟的并且最终被解析为Pawn.GetPos(bool)
这一事实无关紧要,在已经设置了之后发生了。
这就是你得到你看到的输出的原因。
答案 1 :(得分:0)
我认为这是因为触发器。 你做了v.getPos();没有布尔。 因为没有插入bool我认为它的值是标准的假并且返回4 istead。