我注意到,若是在接口上將參數指定爲可選參數,則使用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); } }
所提議的特徵彷佛給程序員增長了許多不便,表明性功率沒有相應的增長。 這個功能的顯着優點是什麼證實了用戶成本的增長?