F# 可区分联合与 C# 类层次结构

发布于 2024-12-03 09:14:58 字数 391 浏览 6 评论 0原文

我有以下代码:

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 )

I have the following code:

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 }
}

and I wonder if it is a good translation from F#

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

??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我纯我任性 2024-12-10 09:14:58

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

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

关于您的代码还有一点 - 由于您无法添加新案例,F# 编译器知道您需要的唯一案例是 BC。因此,block_3 永远无法执行,这意味着您只能编写:

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

F# discriminated unions correspond to OO class hierarchies quite closely, so this is probably the best option. The most notable difference is that you cannot add new cases to a discriminated union without modifying the type declaration. On the other hand, you can easily add new functions that work with the type (which roughly corresponds to adding new virtual methods in C#).

So, if you don't expect to add new inherited classes (cases), then this is the best option. Otherwise, you may use F# object types (or other options, depending on the scenario).

One more point regarding your code - since you cannot add new cases, F# compiler knows that the only cases you need are for B and C. As a result, the block_3 can never be executed, which means that you can write just:

let my_fct x = 
  match x with 
  | B -> ( block_1 ) 
  | C -> ( block_2 ) 
撞了怀 2024-12-10 09:14:58

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

Object-Browser of the types

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

我认为对于这种“else”情况,在 C# 中抛出异常会更好。

yes this is more or less the same as F# does anyhow.
In this case (no values added) - F# seems to translate this into a classs for "a" and some Tags (enumeration). The class for "a" just has some static properties for B and C, and some methods to check if an object of type "a" is "B" or "C" (see below)

Object-Browser of the types

But you don't need the "_ -> (block_3)" case, because this can never be matched (F# knows all the possible cases and will warn you).

I think it's better if you throw an exception in C# for this "else" case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文