gpt4 book ai didi

c# - 可选参数 : reversed precedence if override of overload exists

转载 作者:行者123 更新时间:2023-11-30 20:44:26 25 4
gpt4 key购买 nike

我想知道以下行为:

public class A {
public virtual void Do() { Console.WriteLine("A"); }
}

public class B : A {
public override void Do() { Console.WriteLine("B override"); }
public void Do(int value = 0) { Console.WriteLine("B overload"); }
}

class Program {
public static void Main() {
new B().Do(); // ---> Console: "B overload"
}
}

我希望具有确切签名的重载优先于具有可选参数的另一个重载:我希望控制台中显示“B override”。相反,程序将“B 重载”写入控制台。

甚至 resharper 也失败并落入陷阱:

enter image description here

... Resharper 说带有可选参数的重载被带有精确签名的重载隐藏了,但实际上恰恰相反。

现在,如果您删除继承,那么它会按预期运行并且 resharper 警告是合法的:

public class B {
public virtual void Do() { Console.WriteLine("B override"); }
public void Do(int value = 0) { Console.WriteLine("B overload"); }
}

class Program {
public static void Main() {
new B().Do(); // ---> Console: "B override"
}
}

那么问题来了:解释这个观察结果的优先规则是什么?为什么具有精确签名的重载不优先于具有可选参数的另一个重载,以防具有精确参数的重载覆盖基本实现?

最佳答案

Why an overload with exact signature doesn't have precedence over another overload with optional parameters in case that the overload with exact parameters overrides a base implementation?

基本上这是遵循规范规则的编译器,尽管在这种情况下它们令人惊讶。 (第 7.6.5.1 节是 C# 5 规范的相关部分。)

编译器首先查看“最深”类型 - 即具有目标编译时类型的类型(在本例中为 B)并尝试找到适用的函数成员 忽略任何重写基类中声明的方法:

The set of candidate methods is reduced to contain only methods from the most derived types: For each method C.F in the set, where C is the type in which the method F is declared, all methods declared in a base type of C are removed from the set.

和:

The intuitive effect of the resolution rules described above is as follows: To locate the particular method invoked by a method invocation, start with the type indicated by the method invocation and proceed up the inheritance chain until at least one applicable, accessible, non-override method declaration is found. Then perform type inference and overload resolution on the set of applicable, accessible, non-override methods declared in that type and invoke the method thus selected. If no method was found, try instead to process the invocation as an extension method invocation.

因此在您的情况下,编译器 考虑新引入的方法,发现它适用(使用默认参数值)并停止搜索。 (即它不查看基类中声明的方法)。此时,候选函数成员集只有一个条目,因此此时没有真正的重载决议要执行。

我有一个 article on overloading它显示了这种情况,不是使用可选参数而是使用不同的参数类型 - 请参阅“继承”部分。

关于c# - 可选参数 : reversed precedence if override of overload exists,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29392335/

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