使用受歧视的联合建模多级继承

时间:2009-12-09 01:08:30

标签: f#

是否有建议的方法来模拟F#中的多个继承级别,可能是使用区别联合?

在C#中使用以下内容:

class Expr { }
class SourceExpr : Expr { }
class JoinExpr : SourceExpr { }
class TableExpr : SourceExpr { }

我在F#中完成了这个:

type SourceExpr =
    | Join of JoinExpr
    | Table of TableExpr

type Expr = 
    | Source of SourceExpr
    | ...

有更好的方法吗?这是否提供与继承相同的多态行为?

2 个答案:

答案 0 :(得分:8)

如果没有更多信息,很难在这里过于规范。根据您要执行的操作,使用类层次结构或区分联合(DU)可能更有意义。最常见/最常见的权衡是类层次结构是“开放的”而DU是“封闭的”。也就是说,您可以轻松地将新类型添加到类层次结构中,但添加新操作(基类上的抽象方法)需要更改所有现有类。相反,使用DU,您可以轻松添加新操作(模式匹配数据类型的功能),但是要添加新案例(子类),您必须重新定义类型并更新所有现有操作以处理新案例。 (这有时被称为“表达问题”。)

一个对DUs有益的典型例子是编译器;你有一个语言抽象语法树,其中语言和树结构是固定的,但你可以在编译器内编写许多不同的树变换操作。适用于类层次结构的典型示例是UI框架;你有一些基类定义了小部件必须提供的所有操作(Draw,Resize,...),但用户将添加自己的自定义子类型和额外的功能。

答案 1 :(得分:0)

您可以使用F#中的继承对类进行建模,就像在C#中一样....或者......您可以在显示时使用受歧视的联合对需求进行建模。

不,有区别的联盟不允许相同类型的多态行为,特别是如果添加新案例,您可能需要修改所有模式匹配。

它有它的优点,我倾向于在F#中使用有区别的联合编写代码,在C#中继承代码......除非......我对可扩展性有特别的关注。

你没有使用被禁用的联盟对任何级别的继承进行建模......你正在将苹果与胡萝卜进行比较。

你可以在两种范式中对相同的要求进行建模......我会在你的上下文中使用歧视联盟....我认为它会使代码更容易阅读....但是那样做了主观的。