此博客的最后一部分解释了:http://lostechies.com/jimmybogard/2010/05/18/caveats-of-c-4-0-optional-parameters/
但我仍然想知道原因。
我最近遇到了Scala的默认参数。
在Scala中,被调用者为具有默认值的参数提供实际值。 因此,不必重新编译所有调用者以使用更新的默认参数值。
如果Scala可以做到,我猜C#也可以做到。
那么,为什么?他们为什么设计它容易出错?
编辑:
容易出错可能过于强烈,所以我的问题更像是这样:
为什么它的设计方式是默认参数的版本化不会影响调用者?
答案 0 :(得分:6)
来自Eric Lippert本人的话:
也就是说,他们认为默认值以某种方式“烘焙”到 被叫方。
实际上,默认值是来电者;关于的代码 被叫方不受影响,来电者变为
M("{0}", false);
这个事实的结果是,如果你改变了 没有重新编译调用者的库方法的默认值 那个库,调用者不会因为而改变他们的行为 默认值已更改。如果您发布方法M的新版本 将默认值更改为true,这对那些调用者来说无关紧要。直到 一个带有一个参数的M的调用者被重新编译它将始终通过 假的。
这可能是一件好事。将默认值从false更改为true是一个 打破变革,人们可能会争辩说现有的来电者应该是 绝缘不断。 [强调我的]
这是一个相当严重的版本问题,也是一个主要原因 为什么我们在向C#添加默认参数时推迟了这么久。该 这里的教训是仔细考虑长期的情景 术语。如果您怀疑自己将更改默认值 并且您希望调用者在不重新编译的情况下获取更改, 不要在参数列表中使用默认值;做两个重载, 其中参数较少的一个调用另一个。
Source: Optional argument corner cases, part four(full series)
至于Scala中为什么会有所不同:也许C#中存在技术上的限制。如果你查看可选参数的4个帖子,你会注意到他们有许多角落要记住。
如果它不是技术限制,那么很可能是一个管理问题。与often indicated:
一样以下是我们如何设计C#4。
首先,我们列出了我们可以想到的每个可能的功能 添加到语言中。
然后我们将功能分解为"这很糟糕,我们绝对不能这样做" "这太棒了,我们必须这样做"和"这很好但是不要这样做 这次这样做"。
然后我们看看我们有多少预算要设计,实施,测试, 记录,运输和维护"必须有"功能和发现 我们超出预算100%。
所以我们从"得到了"移动了一堆东西。桶到了#34;好看 拥有"桶。
我们每一分钟都花在设计,实施,测试,记录或 保持不错的功能X是一分钟,我们不能花在真棒上 特征A,B,C,D,E,F和G.我们必须无情地优先考虑 我们只做最好的功能。索引属性会 很好,但很好,在任何地方甚至接近实际上都不够好 实施。