【问题标题】:Overloaded function and parameter of different types重载不同类型的函数和参数
【发布时间】:2014-03-20 15:08:45
【问题描述】:

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?

【问题讨论】:

  • id == 0 ? User.Identity.Name : id的类型是什么???
  • 这是我所期望的。

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


【解决方案1】:

一般来说,除了一些例外,例如使用反射,你是对的,重载方法实际上没有任何“功能”,而不是创建一个完全不同名称的新方法。这是因为,正如已经说过的,重载决议是在编译时完成的(同样,有一些罕见的例外,一般来说,应该避免)而不是在运行时。

所以你真的没有获得任何东西,就功能而言,给每个方法一个不同的名字。这主要是为了作为程序员的方便,并且为了让您的类型的用户清楚该方法执行相同的操作,它只是使用几个选项之一来完成它。

【讨论】:

    【解决方案2】:

    重载在编译时解决,而不是在运行时解决。三元运算符?: 在运行时进行评估。所以在编译时,编译器不知道要链接到哪个函数重载,因为它不知道是否id==0。这就是您的第二个示例有效的原因,因为在那里调用的重载可以在编译时解决。

    重载的原因是方便以不同数量或类型的参数调用相同的逻辑函数。

    【讨论】:

    • 话虽如此,您当然可以通过使用dynamic(如ConfigQuery(id==0?(dynamic)User.Identity.Name:id))在运行时解决重载问题
    【解决方案3】:

    是的,这是合理的行为。

    请记住,调用的重载是在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) 使用“更合适”的名称

    【讨论】:

      【解决方案4】:

      你没有发布你得到的错误,但看起来失败与重载无关。

      错误是因为三元运算符? 无法获取字符串和int 参数,它们需要是相同类型或它们之间有隐式转换。

      this 的帖子解释得很好。

      编辑:
      从规范中可以理解失败的原因:

      如果 x 的类型为 X,y 的类型为 Y,则:

      • 如果存在从 X 到 Y,但不存在从 Y 到 X 的隐式转换(第 6.1 节),则 Y 是条件表达式的类型。

      • 如果存在从 Y 到 X 而不是从 X 到 Y 的隐式转换(第 6.1 节),则 X 是条件表达式的类型。

      • 否则无法确定表达式类型,出现编译时错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-24
        • 1970-01-01
        • 1970-01-01
        • 2015-05-01
        • 1970-01-01
        • 2021-02-18
        • 1970-01-01
        相关资源
        最近更新 更多