2017-03-03 11 views
3

System.Data.Common.DbParameterクラスを模倣する型を実装しています。このタイプは、C#、VB.NET、およびF#プロジェクトで使用されます。F#:DUを使用してプロパティの型を制限する

type myNewType = 
    member val Direction: int = 0 with get,set 
    member val Value: Object = null with get,set 

クラスのValue特性は、型オブジェクトである:ここでスリム化例です。私のタイプでは、そのプロパティを文字列またはバイト配列に制限したいと考えています。私はDUが完璧かもしれないと思っていましたが、私は構文が不明です。ここにいくつかの擬似コードがあります:

type Value = 
| Value of String or byte[] 

type myNewType = 
    member val Direction: int = 0 with get,set 
    member val Value: Value = [||] with get,set 

構文を教えてもらえますか?事前のおかげであなたはDUを使用している

答えて

5
type DbParameterValue = 
| StringValue of s: string 
| BytesValue of bytes: byte[] 

type myNewType() = 
    member val Direction = 0 with get, set 
    member val Value: DbParameterValue = BytesValue([||]) with get, set 

メンバーのval構文は常に私を引き上げます。最も難しいのは、良いデフォルト値を計算することです。空のバイト配列はここでは理想的ではないと思いますが、おそらく初期状態を設定するためのコンストラクタパラメータを取るでしょうか?

4

あなたは明示的には以下の

type Value = 
| StringVal of string 
| ByteVal of byte[] 
| Initial 

type myNewType = 
    member val Direction: int = 0 with get,set 
    member val Value: Value = Initial with get,set 

Initialがの一種として使用される場合にはのようなものを試してみてください

を採用したいの選択肢を綴るする必要がデフォルト。

3

頭字語「DU」は、「Discriminated Union」の略語です。つまり、それはの間でを区別できるタイプの和集合です。ここでは「弁別」が重要です。つまり、ユニオンの各タイプには特別なラベルが「タグ付け」されており、これらのラベルを使用してどのタイプであるかを知ることができます。あなたはどこから値を得たとき、あなたはあなたが得た値の種類を判断するためにラベルを使用することができます

let v1 = StringValue "abc" 
let v2 = ByteValue [|1b;2b;3b|] 

:この型の値を作成するには

type Value = StringValue of string | ByteValue of byte[] 

、あなたが意味その場合、指定します。

match v with 
| StringValue s -> printfn "Got a string: %s" s 
| ByteValue a -> printfn "Got %d bytes" a.Length 

一部の言語には "uniscriminated unions"があります。たとえば、TypeScriptでは次のようにすることができます。

type T = string | number; 
var x : T = 5; 
x = "abc" 
if (typeof x === "string") return x.length; 

F#には該当しません。

4

F#の観点から、方向性と価値の2つの差別化された結合を使用すると、ドメインを最もよくモデル化できるようです。

type Direction = 
    |Input 
    |InputOutput 
    |Output 
    |ReturnValue 

type Value = 
    |String of string 
    |Bytes of byte[] 

DBParameterタイプで組み合わせてください。私はこのためにレコード構文をお勧めします:

type DBParameter = {Direction : Direction; Value : Value} 

は、その後、あなたがこのようにインスタンスを作成することができます。

let dbParam = {Direction = ReturnValue; Value = String "Some return value"} 

あなたは判別組合は、他の.NET言語で消費される方法を検討する必要があります。この目的のために、コンポーネント設計ガイドラインのsection 5.1を参照すると役立ちます。

関連する問題