【问题标题】:Extension method design guidelines: should a like method name be the same for the sub and super class?扩展方法设计指南:子类和超类的类似方法名称是否应该相同?
【发布时间】:2011-07-30 20:13:59
【问题描述】:

我刚读完 Krzysztof Cwalina 和 Brad Abrams 在框架设计指南第 2 版中关于扩展成员的部分,但没有找到这方面的示例。我的问题涉及 F# 库中的超类和子类,但我希望答案与所有​​ .NET 语言相关。

F# 有两种类型,超类型Expr 和子类型Expr<'a>,后者只是前者的类型化版本的包装器。这些是用于引用表达式的类型。

如果我想在这些类型上定义扩展方法来评估它们,那将是一个更好的设计:

  1. 按照 F# PowerPack 的做法,并在 Expr 上使用不同名称 EvalUntyped() : Expr -> obj 和 Eval() : Expr<'a> -> 'a 在 Expr<'a> 上定义方法。
  2. 如果你拥有这些类型并使用相同的名称,请做一些更接近你所做的事情(其中超类型上的方法可以被认为是虚拟的,而子类型上的方法可以被认为是覆盖超级虚拟方法)。即Eval() : Expr -> obj 上Expr 和Eval() : Expr<'a> -> 'a 上Expr<'a>。

第二个选项对我来说似乎更正确,但我想遵循可能存在的任何设计准则:是否有任何权威优先级(假设他们在 PowerPack 中“错误”地理解了它)?

【问题讨论】:

  • 我不知道建议是什么。需要注意的一点是,如果Eval 是标准虚方法,那么派生类型将无法更改其类型。 (参数必须是 Expr。将结果从 obj 更改为 'a 也是不允许的,但它会是类型声音。)
  • 啊,托马斯好点。也许更好的类比是IEnumerable.GetEnumerator() 和IEnumerable<'a>.GetEnumerator()。

标签: .net f#


【解决方案1】:

对此可能没有明确的答案。但是,除非您真的相信 F# PowerPack 的设计确实“错误”,否则我会遵循他们的风格,原因有两个:

  1. 使样式与其他开发人员已经在 F# 和官方扩展中使用的样式保持一致。
  2. 更明确地显示两种方法的返回类型的差异,因为这很重要。

您在回复 Tomas 时的类比是一个很好的类比,但我认为使用此代码的任何其他开发人员可能不会像您那样关注设计。最好与官方风格保持一致,并明确表达您的意图。

【讨论】:

  • 好点大卫,谢谢。框架设计指南还告诫不要为了更好的设计而破坏一致性。我会说,当我第一次遇到 PowerPack 设计时,我确实觉得它很混乱,而且在有类型和无类型的引用之间进行重构时会带来额外的麻烦。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多