gpt4 book ai didi

重写方法的 C# 可选参数

转载 作者:IT王子 更新时间:2023-10-29 03:41:52 26 4
gpt4 key购买 nike

似乎在 .NET Framework 中重写方法时可选参数存在问题。下面代码的输出是:“bb”“啊”.但我期待的输出是:“bb”“bb”.有解决办法吗?我知道它可以通过方法重载来解决,但想知道这样做的原因。该代码在 Mono 中也能正常工作。

class Program
{
class AAA
{
public virtual void MyMethod(string s = "aaa")
{
Console.WriteLine(s);
}

public virtual void MyMethod2()
{
MyMethod();
}
}

class BBB : AAA
{
public override void MyMethod(string s = "bbb")
{
base.MyMethod(s);
}

public override void MyMethod2()
{
MyMethod();
}
}

static void Main(string[] args)
{
BBB asd = new BBB();
asd.MyMethod();
asd.MyMethod2();
}
}

最佳答案

你可以通过调用来消除歧义:

this.MyMethod();

(在 MyMethod2() 中)

它是否是一个错误是棘手的;不过,它看起来确实不一致。 ReSharper 警告您不要更改覆盖中的默认值,如果这有帮助;p 当然,ReSharper 告诉您 this. 是多余的,并且提供为您删除它...这会改变行为 - 因此 ReSharper 也不完美。

它看起来确实可以符合编译器错误的条件,我同意你的看法。我需要非常仔细地看,以确保...当您需要他时 Eric 在哪里,嗯?


编辑:

这里的重点是语言规范;让我们看看 §7.5.3:

For example, the set of candidates for a method invocation does not include methods marked override (§7.4), and methods in a base class are not candidates if any method in a derived class is applicable (§7.6.5.1).

(事实上,§7.4 显然忽略了 override 方法的考虑)

这里有一些冲突....它声明如果派生类中有适用的方法,则不使用base方法 - 这将导致我们派生 方法,但与此同时,它表示不考虑标记为 override 的方法。

但是,§7.5.1.1 然后指出:

For virtual methods and indexers defined in classes, the parameter list is picked from the most specific declaration or override of the function member, starting with the static type of the receiver, and searching through its base classes.

然后 §7.5.1.2 解释了在调用时如何计算值:

During the run-time processing of a function member invocation (§7.5.4), the expressions or variable references of an argument list are evaluated in order, from left to right, as follows:

...(snip)...

When arguments are omitted from a function member with corresponding optional parameters, the default arguments of the function member declaration are implicitly passed. Because these are always constant, their evaluation will not impact the evaluation order of the remaining arguments.

这明确强调它正在查看参数列表,该列表先前在 §7.5.1.1 中定义为来自最具体的声明或覆盖。这似乎是 §7.5.1.2 中提到的“方法声明”,因此传递的值应该是从最派生到静态类型。

这表明:csc 有一个 bug,它应该使用 derived 版本(“bbb bbb”),除非它受到限制(通过 base.,或者转换为基类型)以查看基方法声明(§7.6.8)。

关于重写方法的 C# 可选参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8909811/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com