2011-09-07 15 views
6

を階層C#クラス対組合を区別:F#が、私は次のコードを持っている

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) 

から良い訳ですかしら?

+0

私はそれが大丈夫だと思います。あなたが欠けていることを除いて。 block_1、block_2、block_3の後に –

+2

私の無知を許しますが、F#スニペットでは 'block_3'は決して実行できません(代数データ型は私が知る限り「閉じています」)。また、翻訳で多形性を使うべきだと私は思っていますか? – delnan

+0

あなたはblock_3について完全に正しいです。 – Hugo

答えて

11

F#識別された共用体はOOクラス階層に非常によく対応しているため、これはおそらく最適なオプションです。最も顕著な違いは、型宣言を変更することなく、識別された共用体に新しいケースを追加できないことです。一方、その型で動作する新しい関数を簡単に追加することができます(これは、C#で新しい仮想メソッドを追加することにほぼ相当します)。

新しい継承クラス(ケース)を追加する予定がない場合は、これが最適なオプションです。それ以外の場合は、F#オブジェクトタイプ(またはシナリオに応じて他のオプション)を使用することができます。

あなたのコードに関するもう1つのポイント - 新しいケースを追加することができないので、F#コンパイラは必要なケースがBCであることを知っています。その結果、block_3はあなただけ書くことができることを意味し、実行することはできません。

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

F#がとにかくないようはい、これは同じ多かれ少なかれです。 この場合(値は追加されません) - F#はこれを "a"といくつかのタグ(列挙)のクラスに変換しているようです。 「」ちょうどBおよびCのためのいくつかの静的プロパティ、およびいくつかのメソッドを有するのクラスタイプのオブジェクトは、「」「B」または「C」である場合

Object-Browser of the types

(下記参照)をチェックしますしかし、 "_ - >(block_3)"の場合は必要ありません。これは決して一致することはありません(F#はすべての可能な事例を知っており、警告します)。

この「else」のケースでは、C#で例外をスローするとよいと思います。

+0

私はTomasがそれをより良く置いたと思います;) – Carsten

関連する問題