开发者

F# discriminated unions versus C# class hierarchies

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 go开发者_Python百科od translation from F#

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

??


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 ) 


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)

F# discriminated unions versus C# class hierarchies

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜