我注意到,若是在接口上将参数指定为可选参数,则使用C#4中的可选参数,您没必要在任何实现类上使该参数可选: 程序员
public interface MyInterface { void TestMethod(bool flag = false); } public class MyClass : MyInterface { public void TestMethod(bool flag) { Console.WriteLine(flag); } }
所以: 框架
var obj = new MyClass(); obj.TestMethod(); // compiler error var obj2 = new MyClass() as MyInterface; obj2.TestMethod(); // prints false
有谁知道为何可选参数设计为这样工做? spa
一方面,我认为覆盖接口上指定的任何默认值的能力是有用的,但老实说,我不肯定您是否应该可以在接口上指定默认值,由于这应该是一个实现决策。 设计
另外一方面,这种断开意味着您不能老是交替使用具体类和接口。 固然,若是在实现上指定了默认值,那么这不是问题,可是若是你将具体类做为接口公开(使用一些IOC框架来注入具体的类),那么真的没有具备默认值的点,由于调用者不管如何都必须始终提供它。 版本控制
由于默认参数在编译时解析,而不是运行时。 所以,默认值不属于被调用的对象,而是属于被调用的引用类型。 code
可选参数仅使用属性标记。 此属性告诉编译器在调用站点插入该参数的默认值。 对象
调用obj2.TestMethod();
被obj2.TestMethod(false);
取代obj2.TestMethod(false);
当C#代码被编译到IL时,而不是在JIT时。 接口
所以,在某种程度上,调用者始终使用可选参数提供默认值。 这也会对二进制版本控制产生影响:若是更改默认值但不从新编译调用代码,它将继续使用旧的默认值。 开发
另外一方面,这种断开意味着您不能老是交替使用具体类和接口。 get
可选参数有点像我理解的宏替换。 从方法的角度来看,它们并非真正的可选项。 若是您转换为接口,那么您看到的行为会致使不一样的结果。
更新: 这个问题是我2011年5月12日博客的主题。感谢您提出的好问题!
假设您有一个描述的接口,以及一百个实现它的类。 而后你决定使其中一个接口的方法的参数之一可选。 您是否建议正确的作法是让编译器强制开发人员找到该接口方法的每一个实现,并使参数也可选?
假设咱们这样作了。 如今假设开发人员没有实现的源代码:
// in metadata: public class B { public void TestMethod(bool b) {} }
// in source code interface MyInterface { void TestMethod(bool b = false); } class D : B, MyInterface {} // Legal because D's base class has a public method // that implements the interface method
D的做者应该如何使这项工做? 您是否须要在您的世界中打电话给B的做者并要求他们向他们发送新版本的B,使该方法具备可选参数?
那不会飞。 若是两个人打电话给B的做者,而且其中一我的想要默认为真,其中一我的想要它是假的,该怎么办? 若是B的做者拒绝一块儿玩怎么办?
也许在那种状况下他们会被要求说:
class D : B, MyInterface { public new void TestMethod(bool b = false) { base.TestMethod(b); } }
所提议的特征彷佛给程序员增长了许多不便,表明性功率没有相应的增长。 这个功能的显着优点是什么证实了用户成本的增长?