McK*_*Kay 112 c# overload-resolution
我有这门课
public class Overloaded
{
public void ComplexOverloadResolution(params string[] something)
{
Console.WriteLine("Normal Winner");
}
public void ComplexOverloadResolution<M>(M something)
{
Console.WriteLine("Confused");
}
}
Run Code Online (Sandbox Code Playgroud)
如果我这样称呼它:
var blah = new Overloaded();
blah.ComplexOverloadResolution("Which wins?");
Run Code Online (Sandbox Code Playgroud)
它写入Normal Winner
控制台.
但是,如果我添加另一种方法:
public void ComplexOverloadResolution(string something, object somethingElse = null)
{
Console.WriteLine("Added Later");
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
以下方法或属性之间的调用不明确:>'
Overloaded.ComplexOverloadResolution(params string[])
'和'Overloaded.ComplexOverloadResolution<string>(string)
'
我可以理解,添加一个方法可能会引入一个电话不确定性,但它的两种方法之间的不确定性已经存在的(params string[])
和<string>(string)
!很明显,模糊性中涉及的两种方法都不是新添加的方法,因为第一种是params,第二种是泛型.
这是一个错误吗?该规范的哪一部分说应该是这种情况?
Eri*_*ert 107
这是一个错误吗?
是.
恭喜,您在重载解析中发现了一个错误.该错误在C#4和5中重现; 它不会在语义分析器的"Roslyn"版本中重现.我已经通知了C#5测试团队,希望我们能够在最终版本发布前对其进行调查和解决.(一如既往,没有承诺.)
接下来是正确的分析.候选人是:
0: C(params string[]) in its normal form
1: C(params string[]) in its expanded form
2: C<string>(string)
3: C(string, object)
Run Code Online (Sandbox Code Playgroud)
候选零显然不适用,因为string
不可转换为string[]
.剩下三个.
在这三者中,我们必须确定一种独特的最佳方法.我们通过对剩下的三个候选人进行成对比较来做到这一点.有三对这样的对.一旦我们剥离了省略的可选参数,它们都具有相同的参数列表,这意味着我们必须进入规范7.5.3.2节中描述的高级tiebreaking轮次.
哪个更好,1还是2?相关的决胜局是泛型方法总是比非泛型方法更糟糕.2比1差.所以2不能成为胜利者.
哪个更好,1还是3?相关的决胜局是:仅适用于其扩展形式的方法总是比适用于其正常形式的方法更糟糕.因此1比3差.所以1不能成为赢家.
哪个更好,2或3?相关的决胜局是泛型方法总是比非泛型方法更糟糕.2比3差.所以2不能成为胜利者.
要从一组多个适用候选者中选择,候选者必须是(1)不败,(2)击败至少一个其他候选者,以及(3)是具有前两个属性的唯一候选者.候选人三人被其他候选人击败,至少击败另一名候选人; 它是唯一具有此属性的候选人.因此候选人三是唯一的最佳候选人.它应该赢.
不仅C#4编译器出错了,因为你正确地注意到它报告了一个奇怪的错误信息.编译器错误地重载分辨率分析有点令人惊讶.它错误消息的错误是完全不足为奇的; 如果无法确定最佳方法,"模糊方法"错误启发式基本上从候选集中选择任意两种方法.如果事实上有一个模糊性,它就不是很擅长找到"真正的"歧义.
人们可能会合理地问为什么会这样.找到两种 "毫不含糊的模糊"方法是非常棘手的,因为"更好"关系是不及物的.有可能提出候选1优于2,2优于3,3优于1的情况.在这种情况下,我们不能比将其中两个选为"模糊的"更好.
我想改进Roslyn的这种启发式方法,但它是一个低优先级.
(向读者练习:"设计一个线性时间算法来识别一组n个元素中唯一最好的成员,其中良好关系是不及物的"是我在为这个团队采访的那天被问到的问题之一.它不是一个非常难的算法;试一试.)
我们推迟向C#添加可选参数的原因之一是它引入过载解析算法的复杂模糊情况的数量; 显然我们没有做对.
如果您想输入Connect问题进行跟踪,请随意.如果你只是想让它引起我们的注意,那就考虑一下吧.我会在明年跟进测试.
谢谢你引起我的注意.为错误道歉.
该规范的哪一部分说应该是这种情况?
第7.5.3节(重载决策),以及第7.4节(成员查找)和第7.5.2节(类型推断).
请特别注意第7.5.3.2节(更好的函数成员),其中部分地说"没有相应参数的可选参数从参数列表中删除","如果M(p)是非泛型方法,则m(q)是一般方法,则M(p)优于M(q)."
但是,我不完全理解规范的这些部分,足以知道规范的哪些部分控制了这种行为,更不用说判断它是否合规.
归档时间: |
|
查看次数: |
2887 次 |
最近记录: |