F#区分并集与C#类层次结构

F#区分并集与C#类层次结构,c#,f#,class-hierarchy,c#-to-f#,discriminated-union,C#,F#,Class Hierarchy,C# To F#,Discriminated Union,我有以下代码: 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的好翻译# 有区别的联合与OO类层次结构非常接近,因此这可能是最好的选择。最显著的区别是,在不修改类型声明的情况下,无法

我有以下代码:

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的好翻译#

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

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

关于你的代码还有一点-因为你不能添加新的案例,F#编译器知道你只需要
B
C
的案例。因此,
块_3
永远无法执行,这意味着您可以只写:

let my_fct x = 
  match x with 
  | B -> ( block_1 ) 
  | C -> ( block_2 ) 

是的,不管怎么说,这和F#的做法差不多。 在本例中(没有添加值)-F#似乎将其转换为“a”的类和一些标记(枚举)。“a”的类只有一些B和C的静态属性,以及一些检查“a”类型的对象是“B”还是“C”的方法(见下文)

但是您不需要“->(block_3)”案例,因为这是永远无法匹配的(F#知道所有可能的案例,并会警告您)


我认为最好在C中为这个“else”案例抛出一个异常。

我想没关系。除了你失踪;在block_1、block_2和block_3之后,请原谅我的无知,但它似乎永远不能在F#snippet中执行
block_3
(据我所知,代数数据类型是“闭合的”),那么它为什么会存在呢?另外,我是唯一一个认为翻译应该使用多态性的人吗?关于block_3,你们都完全正确。F#pattern matching编译为程序集中的跳转,因此联合用例的数量是O(1)。为了匹配C#中的性能,您应该有一个int或enum编码的案例号,模式匹配编码为switch语句
let my_fct x = 
  match x with 
  | B -> ( block_1 ) 
  | C -> ( block_2 )