【问题标题】:compiler warning on (ambiguous) method resolution with named parameters带有命名参数的(不明确的)方法解析的编译器警告
【发布时间】:2011-02-09 02:50:15
【问题描述】:

关于以下代码是否应该产生编译器警告的一个问题(它不会)。它声明了两个具有相同名称/返回类型的方法,一个具有附加的带默认值的命名/可选参数。

注意:从技术上讲,该解决方案并不含糊,因为规则明确规定将调用第一个方法。见here, Overload resolution, third bullet point。毫无疑问,这种行为对我来说也很直观。

public void Foo(int arg) { ... }

public void Foo(int arg, bool bar = true) { ...} 

Foo(42); // shouldn't this give a compiler warning?

我认为编译器警告在这里会很直观。虽然代码在技术上是干净的(它是否是一个合理的设计是一个不同的问题:))。

【问题讨论】:

  • 为什么第二种方法有默认参数?正如您的链接所述,如果您调用 Foo(42) 它应该调用第一个方法,因此您的第二个带有默认参数的方法将永远不会被选择...?
  • 问题不在于我用这两种方法设计了一个类。问题是不完美的世界,当第一个方法已经存在(我可能不知道)时,我将第二个方法添加到类中,添加调用,可能会错过(慢)智能感知,并想知道为什么新的没有得到叫。不是一个大问题,但仍然是一个潜在的问题。对我来说,它已经足够接近模棱两可了。如果你告诉我你从来没有意外地实现过两次,那么你就从来没有在一个复杂的项目中编写过代码。
  • @oedo,这里的问题不是关于默认参数,而是为什么编译器在这种情况下不发出警告。问题是开发者可能不知道这个规则。
  • 啊,我明白了,对不起。是的,在这种情况下,我同意你的看法,警告会让校长不感到意外。
  • 打电话给 Eric Lippert ... (stackoverflow.com/users/88656/eric-lippert)

标签: c#-4.0 named-parameters


【解决方案1】:

实际上,我不同意它需要警告。主要问题是,该代码可能合法,如果是这种情况,您必须明确禁用警告。

我的意思是,一般来说,当您收到警告时,您将能够更改代码以消除警告(并且可能同时使代码变得更好)。但在这种情况下,可能是您故意这样做,并且无法更改代码以消除警告。

例如,“无法访问的代码”警告是您可以删除无法访问的代码以消除警告的内容。或者“找不到引用”警告 - 这通常是一个信号,表明您将收到“未定义类型”错误,但如果没有,那么您可以简单地删除引用。或者“前一个 catch 子句已经捕获了所有异常”警告:在这种情况下,您需要更改代码,以便新子句位于 catch-all 之前,或者完全删除 catch。

但重点是,在任何情况下,当您收到警告时,您应该更改您的代码,并且做出更改总是会产生“更好”的代码。但是,在这个问题的情况下,调用并不模棱两可(就编译器而言),我认为您不能争辩说编写这样的代码总是是一个错误,所以不应该有警告。

如果编译器对每一个你做了一些可能不是最好的想法的情况发出警告,那么我们就会被警告淹没!

【讨论】:

  • 也许应该有一个代码分析规则...找不到。扩展方法(在我看来是一个不太严重的情况)在分辨率和(没有警告)方面表现相同。但是我确实觉得我问的问题比无法访问的代码更严重。
  • 是的,我认为它是 fxcop 之类的好人选。
  • 故意这样做有什么意义吗?由于第二个参数的默认值永远不会被使用,这使得它成为冗余代码。
【解决方案2】:

警告是为了通知程序员潜在的愚蠢错误。这是一个可能产生愚蠢错误的区域,所以是的,它应该产生警告。您是否正在尝试形成请愿书?

【讨论】:

    猜你喜欢
    • 2015-08-19
    • 2018-10-27
    • 1970-01-01
    • 2012-01-02
    • 2019-10-18
    • 2021-11-17
    • 1970-01-01
    相关资源
    最近更新 更多