gpt4 book ai didi

c# - 如果不涉及歧义,为什么添加方法会添加歧义调用

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

我有这门课

public class Overloaded
{
public void ComplexOverloadResolution(params string[] something)
{
Console.WriteLine("Normal Winner");
}

public void ComplexOverloadResolution<M>(M something)
{
Console.WriteLine("Confused");
}
}

如果我这样调用它:

        var blah = new Overloaded();
blah.ComplexOverloadResolution("Which wins?");

它写道 Normal Winner到控制台。

但是,如果我添加另一种方法:

    public void ComplexOverloadResolution(string something, object somethingElse = null)
{
Console.WriteLine("Added Later");
}

我收到以下错误:

The call is ambiguous between the following methods or properties: > 'Overloaded.ComplexOverloadResolution(params string[])' and 'Overloaded.ComplexOverloadResolution<string>(string)'

我能理解添加一个方法可能会引入调用歧义,但这是两个已经存在的方法之间的歧义(params string[])<string>(string) !显然歧义涉及的两个方法都不是新添加的方法,因为第一个是params,第二个是generic。

这是一个错误吗?规范的哪一部分说应该是这种情况?

最佳答案

Is this a bug?

是的。

恭喜,您发现了重载解析中的错误。该错误在 C# 4 和 5 中重现;它不会在语义分析器的“Roslyn”版本中重现。我已经通知了 C# 5 测试团队,希望我们能在最终版本发布之前调查并解决这个问题。 (一如既往,没有 promise 。)

正确的分析如下。候选人是:

0: C(params string[]) in its normal form
1: C(params string[]) in its expanded form
2: C<string>(string)
3: C(string, object)

候选零显然不适用,因为string 不能转换为string[]。剩下三个。

在这三种方法中,我们必须确定一种独特的最佳方法。我们通过对剩下的三个候选者进行成对比较来做到这一点。有三个这样的对。一旦我们去掉省略的可选参数,它们都有相同的参数列表,这意味着我们必须进入规范第 7.5.3.2 节中描述的高级决胜回合。

哪个更好,1 还是 2?相关的决胜局是泛型方法总是比非泛型方法差。 2 比 1 差。所以 2 不可能是赢家。

哪个更好,1 还是 3?相关的决胜局是:仅适用于其扩展形式的方法总是比适用于其正常形式的方法差。因此 1 比 3 差。所以 1 不可能是赢家。

哪个更好,2 个还是 3 个?相关的决胜局是泛型方法总是比非泛型方法差。 2 比 3 差。所以 2 不可能是赢家。

要从一组多个适用的候选人中选出,候选人必须 (1) 不败,(2) 击败至少一名其他候选人,并且 (3) 是具有前两个属性的唯一候选人。候选人三没有被其他候选人击败,并且击败了至少一名其他候选人;它是唯一具有此属性的候选人。因此候选三是 unique best candidate 。它应该赢。

不仅 C# 4 编译器出错了,正如您正确注意到的那样,它报告了一条奇怪的错误消息。编译器错误地进行重载解析分析有点令人惊讶。它得到错误消息是完全不足为奇的;如果无法确定最佳方法,“模棱两可的方法”错误启发式基本上会从候选集中选择任意两种方法。它不太擅长发现“真正的”歧义,如果确实存在的话。

有人可能会问为什么会这样。很难找到两个“毫不含糊”的方法,因为“优”关系不及物。可能会出现候选 1 优于 2、2 优于 3、3 优于 1 的情况。在这种情况下,我们最好选择其中两个作为“模棱两可的”。

我想为 Roslyn 改进这个启发式算法,但它的优先级很低。

(给读者的练习:“设计一个线性时间算法来识别一组 n 个元素的唯一最佳成员,其中优关系是不及物的”是我为这个团队面试的那天被问到的问题之一. 这不是一个很难的算法;试一试。)

我们推迟向 C# 添加可选参数的原因之一是它在重载解析算法中引入了很多复杂的不明确情况;显然我们没有做对。

如果您想输入一个连接问题来跟踪它,请随意。如果您只想引起我们的注意,请考虑完成。明年我会跟进测试。

感谢您提醒我注意此事。为错误道歉。

关于c# - 如果不涉及歧义,为什么添加方法会添加歧义调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8674512/

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