【发布时间】:2015-03-25 08:39:08
【问题描述】:
C# 允许使用optional parameters:可以指定值,以防在调用中省略参数,然后编译器自己指定值。
例子:
public interface IFoo {
void SomeMethod (int para = 0);
}
这个想法很有用,但问题是可以在类层次结构的不同级别上定义多个“默认值”。示例:
public class SubFoo : IFoo {
public void SomeMethod (int para = 1) {
//do something
}
}
如果以后有人打电话:
SubFoo sf = new SubFoo ();
sf.SomeMethod ();
Foo f = sf;
f.SomeMethod ();
结果是第一次调用是用para 等于1 完成的,第二个调用是para 等于0(作为接口)。这是有道理的,因为编译器添加了默认值,在第一种情况下,this 是 SubFoo,因此默认值为 1。
保持一致性当然取决于程序员,但是当程序员在过程中改变主意并忘记修改所有默认值时,很容易发生这种精神分裂的情况。
问题在于编译器不会警告正在使用不同的默认值,而这可以通过向上移动类层次结构来检查。此外,有些人可能会模仿默认参数:
public class SubFoo2 {
public virtual void SomeMethod () {
SomeMethod(1);
}
public void SomeMethod (int para) {
//do something
}
}
这允许动态绑定并因此一致地覆盖。因此,需要非常小心“实现”默认值的方式。
有没有办法强制检查默认值是否一致(例如使用编译器标志)?如果不是这样,最好至少有一个警告,指出某些事情并不是真正一致的。
【问题讨论】:
-
不,但您可以编写 Roslyn 诊断程序。
-
"忘记修改所有默认值" --- 当这种情况发生时,表明应用程序设计已损坏(或开始损坏)。
-
@zerkms:是的,但正如他们在软件架构中所说:“软件架构的目标是制造万无一失的系统,宇宙的目标是创造更多傻瓜,目前宇宙正在获胜。”.
-
你的意思是
public class SubFoo : IFoo { .. } -
实际上,在接口中包含默认参数声明对我来说似乎很愚蠢。默认参数应该是实现的一部分,而不是接口。
标签: c# default-value optional-parameters