【发布时间】:2011-07-30 20:13:59
【问题描述】:
我刚读完 Krzysztof Cwalina 和 Brad Abrams 在框架设计指南第 2 版中关于扩展成员的部分,但没有找到这方面的示例。我的问题涉及 F# 库中的超类和子类,但我希望答案与所有 .NET 语言相关。
F# 有两种类型,超类型Expr 和子类型Expr<'a>,后者只是前者的类型化版本的包装器。这些是用于引用表达式的类型。
如果我想在这些类型上定义扩展方法来评估它们,那将是一个更好的设计:
- 按照 F# PowerPack 的做法,并在
Expr上使用不同名称EvalUntyped() : Expr -> obj和Eval() : Expr<'a> -> 'a在Expr<'a>上定义方法。 - 如果你拥有这些类型并使用相同的名称,请做一些更接近你所做的事情(其中超类型上的方法可以被认为是虚拟的,而子类型上的方法可以被认为是覆盖超级虚拟方法)。即
Eval() : Expr -> obj上Expr和Eval() : Expr<'a> -> 'a上Expr<'a>。
第二个选项对我来说似乎更正确,但我想遵循可能存在的任何设计准则:是否有任何权威优先级(假设他们在 PowerPack 中“错误”地理解了它)?
【问题讨论】:
-
我不知道建议是什么。需要注意的一点是,如果
Eval是标准虚方法,那么派生类型将无法更改其类型。 (参数必须是Expr。将结果从obj更改为'a也是不允许的,但它会是类型声音。) -
啊,托马斯好点。也许更好的类比是
IEnumerable.GetEnumerator()和IEnumerable<'a>.GetEnumerator()。