2011-07-03 35 views
5

我剛剛閱讀了Krzysztof Cwalina和Brad Abrams撰寫的Framework Design Guidelines 2nd Ed。中有關擴展成員的章節,但沒有找到相應的示例。我的問題涉及F#庫中的超類和子類,但我期望答案與所有​​.NET語言相關。擴展方法設計指南:對於子類和超級類,相似的方法名應該相同嗎?

F#有兩種類型,超類型Expr和子類型Expr<'a>,其中後者僅僅是前者的打印版本的包裝。這些是用於引用表達式的類型。

如果我想確定這些類型的擴展方法評估他們,這將是一個更好的設計:

  1. 做到像F#PowerPack中確實並以不同的名稱EvalUntyped() : Expr -> objExprEval() : Expr<'a> -> 'aExpr<'a>定義的方法。
  2. 如果您擁有類型並使用相同的名稱(在超類型的方法可以被認爲是虛擬的,並且子類型的方法可以被認爲是覆蓋超級虛擬方法)。即在Expr上的Eval() : Expr -> obj和在Expr<'a>上的Eval() : Expr<'a> -> 'a

第二個選擇似乎更正確的給我,但我想任何遵循設計原則有可能是:有沒有這方面的任何權威的優先級(假設他們得到了在PowerPack的「錯誤」)?

+2

我不知道這些建議是什麼。有一點需要注意的是,如果'Eval'是一個標準的虛擬方法,那麼派生類型將無法改變它的類型。 (參數必須是'Expr',將結果從'obj'改爲'a'也是不允許的,但它會是類型聲音。) –

+0

啊,好點Tomas。也許更好的比喻是'IEnumerable.GetEnumerator()'和'IEnumerable <'a> .GetEnumerator()'。 –

回答

1

可能還沒有確定的答案。但是,除非你真的相信的F#PowerPack中的確得到了設計「錯誤」的,我會按照自己的風格,原因有二:

  1. 爲了保持風格,還有什麼其他的開發人員已經在F#和官方擴展與工作一致。
  2. 更明確地顯示兩種方法的返回類型的差異,因爲它確實很重要。

您在Tomas的回覆中的比喻是一個很好的例子,但我會假設其他任何使用此代碼的開發人員可能不會像您一樣對設計給予足夠的關注。最好與官方風格保持一致,並且明確表達自己的意圖。

+0

好點大衛,謝謝。即使對於更好的設計,框架設計指南也提醒注意不要破壞一致性。我會說,當我第一次遇到PowerPack設計時,我發現它確實令人困惑,並且在打字和非打字之間的引用之間造成了額外的麻煩。 –

相關問題