7

我有以下代码:

public abstract class A ...
public class B : A ...
public class C : A ...

void my_fct(A x) {
  if (x is B) { block_1 }
  else if (x is C) { block_2 }
  else { block_3 }
}

我想知道它是否是 F# 的一个很好的翻译

type a = B | C
let my_fct x =
  match x with
  | B -> ( block_1 )
  | C -> ( block_2 )
  | _ -> ( block_3 )

??

4

2 回答 2

13

F# 可区分联合与 OO 类层次结构非常接近,因此这可能是最佳选择。最显着的区别是您不能在不修改类型声明的情况下将新案例添加到有区别的联合中。另一方面,您可以轻松地添加与该类型一起使用的新函数(这大致对应于在 C# 中添加新的虚拟方法)。

因此,如果您不希望添加新的继承类(案例),那么这是最好的选择。否则,您可以使用 F# 对象类型(或其他选项,具体取决于场景)。

关于您的代码的另一点 - 由于您无法添加新案例,F# 编译器知道您需要的唯一案例是 forBC. 结果,block_3永远无法执行,这意味着您可以只写:

let my_fct x = 
  match x with 
  | B -> ( block_1 ) 
  | C -> ( block_2 ) 
于 2011-09-07T12:44:01.540 回答
8

是的,这或多或少与 F# 一样。在这种情况下(未添加值)- F# 似乎将其转换为“a”和一些标签(枚举)的类。“a”的类只有一些 B 和 C 的静态属性,以及一些检查“a”类型的对象是“B”还是“C”的方法(见下文)

对象浏览器类型

但是你不需要 "_ -> (block_3)" 的情况,因为这永远不会被匹配(F# 知道所有可能的情况并且会警告你)。

我认为最好在 C# 中为这种“其他”情况抛出异常。

于 2011-09-07T12:44:38.107 回答