c#虚方法和重写方法中的可选参数

c#虚方法和重写方法中的可选参数,c#,overriding,virtual,C#,Overriding,Virtual,我注意到当使用具有可选参数的虚拟方法时。当您重写此方法并为可选参数使用不同的默认值时,它将使用原始值。我觉得有点奇怪 static void Main(string[] args) { List<Piece> Pieces = new List<Piece>(); Pieces.Add(new Piece()); Pieces.Add(new Pawn()); foreach(var v in Pieces) {

我注意到当使用具有可选参数的虚拟方法时。当您重写此方法并为可选参数使用不同的默认值时,它将使用原始值。我觉得有点奇怪

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
4
这意味着它们都是假的。我甚至可以将参数重命名为不同的名称,并在方法体中使用不同的名称,但其行为仍然相同。这告诉我默认参数值不能被覆盖,因为这是合同的一部分?显然,如果我将该项目转换为Pawn对象,然后调用GetPos(),它将返回3而不是4


我只是觉得这很有趣,因为我希望它的表现会有所不同。我只是想知道我是否遗漏了一些东西,以使这项工作如我最初预期的那样发挥作用。

我确实认为这是因为触发因素。 你做了v.getPos();没有一个女人。
因为没有插入bool,我认为它的值是标准的false,返回4个istead。

可选参数在编译时在调用站点解析

这意味着
v.GetPos()。调用是虚拟的,并且最终解析为
Pawn.GetPos(bool)
这一事实与此无关,这是在设置了可选参数之后发生的


这就是为什么您会看到输出。

可能重复:。感觉我必须回答这个问题。您发现了C#团队不愿意添加可选参数支持的一个原因。他们最终屈服于版本4,该版本大大改善了对COM的支持。可选参数在Office等COM对象模型中非常常见。但是多态性确实使它成为一个泄漏的抽象,COM没有这一特性,编译器只是不知道在运行时调用哪个方法。它只能根据它知道的,它知道的片段来工作。不,它不是,对文本做同样的事情,你们会得到同样的结果。是的。上面的答案是正确的。我也没有注意到,但现在我看到了同样的结果。谢谢你的回复。只是想确定我没有错过什么。有道理,我很少使用可选参数,所以我从来没有想过它们在什么时候被解决。@?当我们为重写的方法设置optionnal参数的默认值时,除了在代码中分配的是这个值之外,我们没有别的选择吗?我对这种行为有一点好奇,我可以找到一些案例,我想要和Rob一样的行为。@Leze不,这不是一个bug,这是记录在案的行为。C#团队从来没有真正想要实现这个特性,这就是为什么它不能与其他语言特性很好地结合的原因之一。直到C#的第四个版本,他们才最终屈服,因为大量的流行需求使COM互操作变得更容易。
1
4