series中的另一个问题“为什么VisualStudio不支持此代码?”...
鉴于功能过载
private string ConfigQuery(string username) {
return "A";
}
private string ConfigQuery(int configId) {
return "B";
}
以下代码是不可能的:
public Config ConfigAPI(int id=0) {
string s = ConfigQuery(id==0?User.Identity.Name:id);
}
但是代码
public Config ConfigAPI(int id=0) {
string s = (id==0?ConfigQuery(User.Identity.Name):ConfigQuery(id));
}
是。这是合理的行为吗?那么为什么我会使用重载函数,而不是给它们更合适的名称,如UserNameConfigQuery,ConfigIdConfigQuery?
答案 0 :(得分:2)
是的,这是合理的行为。
请记住,调用的重载是在compile time vs. runtime确定的。在运行时,id==0?
将不会被评估。
您可能仍希望将重载用于:
myString.Replace('1', '5')
与myString.Replace("1", "5")
)而非使用泛型new Foo(bar)
与new Foo(bar, baz)
或myRegex.Replace("blah", "yada")
与myRegex.Replace("blah", "yada", 2)
)而不是C#为可选参数和默认参数添加的正式支持可能也有意义此外,IntelliSense,代码文档和(正式或导航)搜索将使用不同名称的方法帮助大量,这些方法确实(几乎)相同,只是在类型或数量上有所不同参数。例如,考虑找到并理解:(近似)相同:
QueryConfig(string username)
和QueryConfig(int configId)
使用重载与 UserNameConfigQuery(string username)
和ConfigIdConfigQuery(int configId)
使用“更合适”的名称Replace(string input, string replacement)
和Replace(string input, string replacement, int count)
使用重载与 CountRestrictedReplace(string input, string replacement, int count)
和UnrestrictedReplace(string input, string replacement)
使用“更合适”的名称答案 1 :(得分:2)
重载在编译时解决,而不是在运行时解决。在运行时评估三元运算符?:
。因此,在编译时,编译器不知道链接到哪个函数重载,因为它不知道是否id==0
。这就是你的第二个例子工作的原因,因为在编译时可以解决调用的那个重载。
重载的原因是使用不同数量或类型的参数调用相同的逻辑函数。
答案 2 :(得分:2)
一般来说,除了一些例外,例如使用反射,你是对的,确实没有任何"功能"重载方法而不是完全创建具有不同名称的新方法。这是因为,正如已经说过的那样,重载解析是在编译时完成的(同样,有一些罕见的例外,一般来说应该避免),而不是在运行时。
因此,在功能方面,你实际上并不获得任何东西,而是为每个方法赋予不同的名称。它主要是为了方便程序员,为了让你的类型的用户明白该方法做同样的事情,它只是使用几个选项之一。
答案 3 :(得分:1)
你没有发布你得到的错误,但从外观来看,失败与重载没有任何关系。
错误是因为三元运算符?
无法获取字符串和int参数,它们需要具有相同的类型或它们之间的隐式转换。
this帖子解释得很好。
修改强>
根据规范,您可以了解失败的原因:
如果x的类型为X且y的类型为Y,则为:
如果从X到Y存在隐式转换(第6.1节),而不是从Y到X,则Y是条件表达式的类型。
如果从Y到X存在隐式转换(第6.1节),而不是从X到Y,则X是条件表达式的类型。
否则,无法确定表达式类型,并发生编译时错误。