重载函数和不同类型的参数

时间:2014-03-20 15:08:45

标签: c# visual-studio visual-studio-2012

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?

4 个答案:

答案 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是条件表达式的类型。

  •   
  • 否则,无法确定表达式类型,并发生编译时错误。

  •