为什么这是多余的?


73

我有以下重载的方法:

string Call(string function, Dictionary<string, object> parameters, object body)
string Call(string function, Dictionary<string, object> parameters, JObject body)

现在,我添加了另一个重载:

string Call(string function)
{
    return Call(function, null, (JObject) null);
}

我添加了强制类型转换,JObject以便编译器知道应该使用哪个重载。但是Visual Studio告诉我,转换是多余的。但是为什么没有演员阵容我的电话就不会模棱两可?


19
即使它对编译器来说不是模棱两可的,我还是将其保留在那儿,因为它对于阅读代码的人可能是模棱两可的
Alex

5
@jean不,那不是原因。我告诉编译器要使用哪个重载。而且,使用哪种方法重载也很重要,因为它们可能具有完全不同的实现。nullnull,但此处的强制转换提示应该使用重载。
fero

1
@jean恐怕这又是错误的。演员仅仅是多余的,因为编译器将仍然使用JObject,即使我没有投过载JObject,因为它使用的是相匹配的参数,和最具体的过载null可以匹配任何东西,JObject 不是更加具体object。有关详细说明,请参见Jon Skeet的答案。
fero

Answers:


98

但是为什么没有演员阵容我的电话就不会模棱两可?

因为JObject参数的重载比object参数...的重载“更好”,因为从nullJObject的转换比从null到的转换“更好” object

JObject比更加具体object,因为存在从JObject到的隐式转换object,反之亦然。

例如,如果使用第一个方法的最终参数,string则这两个重载都不会比另一个重载好,并且如果不进行强制转换,则调用是模棱两可的。

有关所有复杂细节,请参见C#5规范的7.5.3节。特别是在这里,第7.5.3.5节(“更好的转换目标”)很重要。


8
即使现在不需要使用该类null进行强制类型转换,但如果不强制转换,也会使调用代码非常脆弱,因为几乎所有其他引用类型重载的添加都会破坏不强制转换的调用代码。我不认为在存在任何可能导致歧义的其他引用类型重载的现实可能性的情况下,甚至在某些情况下特定重载被“更好”的情况下,任何对空引用的强制转换都不是“冗余的”规则,但从任何实际意义上讲都比它更好还很明显。
超级猫

1
顺便说一句,长期以来,我一直认为带有重载的语言将从使用属性的方式中受益匪浅,或者使用某些其他方式来指定某些重载(如果可用),则应视为“首选”,而其他重载应仅被视为“后备” ; 我还认为,如果重载可以指定参数类型为,则将很有帮助null。您知道做这种事情的任何语言吗?
超级猫

@supercat:不,恐怕不是。
乔恩·斯凯特

2
@supercat:C ++ 11及更高版本介绍nullptr_t,可用作参数类型。但是空指针文字仍然可以隐式转换为int和对象指针类型,因此对于重载解析没有太大帮助。...在C ++(所有版本)中,尾随可变参数列表()非常适合使特定的重载不太受欢迎。
Ben Voigt,2015年

8
@supercat如果您真的想手动指定重载,为什么不仅仅拥有一个新的唯一命名的函数呢?
极好的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.