【问题标题】:Optional parameters and method overloading可选参数和方法重载
【发布时间】:2014-07-11 15:50:48
【问题描述】:

我遇到了一个带有三个参数的库方法,所有参数都有默认值:

virtual M(bool b1 = false, string s1 = null, bool b2 = true)

方法M 不应该有参数s1,所以我想删除它,但我不想在DLL 中进行重大更改。客户显然可以忽略s1,但我不想把它留在那里,因为M 可以被覆盖并且参数s1 具有误导性。所以这是我的尝试:

virtual M(bool b1 = false, bool b2 = true)
[Obsolete] virtual M(bool b1, string s1, bool b2 = true)

我认为由于可选参数被编译到调用站点中,现有客户端将继续使用三个参数调用该方法,而未使用 s1 的新客户端或重新编译的客户端将链接到具有两个参数的方法。

每次调用M 都可以解决,除了这个:

M(b2: false);

编译器报告“M(bool, bool)”和“M(bool, string, bool)”之间的调用不明确。

奇怪的是,在参数信息(Ctrl+Shift+Space)中,Visual Studio 仍然显示带有三个参数的方法的默认值(尽管清理和重建、重新启动 VS、卸载和重新加载项目)。

显然我可以通过调用新的M 来解决这个问题,但我很好奇为什么它没有链接。它应该(并且某些东西只是不合时宜,正如过时的参数信息所暗示的那样),还是编译器对此有真正的问题?

编辑

像@pswg 一样,根据@JonSkeet 的建议,我无法在新代码中重现它,所以我想问题变成了:除了重建、重新启动、重新加载以强制 VS 重新链接之外,我还能尝试什么?

【问题讨论】:

  • 我无法仅使用第二个 sn-p 中的方法重现该问题。它对我来说编译得很好。但是,是的,如果可以的话,我建议您更改名称。与客户沟通“方法 M 已过时,现在使用 N”通常比“使用仅接受两个布尔值的 M 的重载”更容易。
  • 我不太明白这个问题。那个叫not怎么会模棱两可呢?
  • @Jon:第二种方法(在新情况下)有两个必需的参数,没有指定。
  • 是的,听起来确实不同步。你能用“新”代码重现这个吗?
  • 你是直接引用dll而不是项目链接吗?

标签: c# overloading optional-parameters


【解决方案1】:

好吧,这在同等程度上既尴尬又有趣(好吧 - 可能比有趣更尴尬)。

编译器是正确的(几乎总是如此!)。我曾假设编译器错误是指我在问题中概述的两个 M 方法,但是带有错误的客户端代码也用三个参数覆盖了原始 M,并且 仍然提供默认值 到所有三个参数。

当我实际添加 [Obsolete] 时,我才发现“第三个 M”(抱歉 - 我只是为了说明而发布它 - 认为这不相关)并收到关于覆盖过时方法的警告。

我认为这可能支持@p.s.w.g的评论!

【讨论】:

  • 在更改哪些参数是可选的时覆盖方法确实令人困惑,这似乎是您的情况(因为虚拟基方法已更改)。另一件令人困惑的事情是,如果覆盖重命名参数,最坏的情况是 b1 在覆盖中重命名为 b2
  • @JeppeStigNielsen:我同意你的看法。我认为这可能是通过删除不需要的额外参数来保持界面清洁的好方法,但它也是虚拟的事实使得这太混乱了。我正在寻找另一种解决方案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
相关资源
最近更新 更多