列挙

2012-01-30 10 views
6

列挙

type Suit = 
    |Clubs = 'C' 
    |Spades = 'S' 
    |Hearts = 'H' 
    |Diamonds = 'D' 

列挙値を指定した場合にどのように私は基礎となるchar値を得るのですか?次のように私は、列挙型を持っていますか 例えばI Suit.Clubsを持っていると「C」

+0

'chは=(箱スーツ)しましょうか? > charは動作しているようですが、私はボクシングを含まないよりエレガントなソリューションがあることを願って... – ildjarn

答えて

11

EDITED:異なるアプローチの 比較:

type Suit = 
    |Clubs = 'C' 
    |Spades = 'S' 
    |Hearts = 'H' 
    |Diamonds = 'D' 

let valueOf1 (e : Suit) = LanguagePrimitives.EnumToValue e 
let valueOf2 (e : Suit) = unbox<char> e 
let valueOf3 (e : Suit) = (box e) :?> char 

とフードの下で:

.method public static 
    char valueOf1 (
     valuetype Program/Suit e 
    ) cil managed 
{ 
    // Method begins at RVA 0x2050 
    // Code size 3 (0x3) 
    .maxstack 8 

    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: ret 
} // end of method Program::valueOf1 


.method public static 
    char valueOf2 (
     valuetype Program/Suit e 
    ) cil managed 
{ 
    // Method begins at RVA 0x2054 
    // Code size 13 (0xd) 
    .maxstack 8 

    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: box Program/Suit 
    IL_0007: unbox.any [mscorlib]System.Char 
    IL_000c: ret 
} // end of method Program::valueOf2 

.method public static 
    char valueOf3 (
     valuetype Program/Suit e 
    ) cil managed 
{ 
    // Method begins at RVA 0x2064 
    // Code size 13 (0xd) 
    .maxstack 8 

    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: box Program/Suit 
    IL_0007: unbox.any [mscorlib]System.Char 
    IL_000c: ret 
} // end of method Program::valueOf3 
+0

'LanguagePrimitives.EnumToValue'を使うことに欠点はありますか?例えば。それは内部的に反射を使用していますか? – ildjarn

+0

編集した私の答え – desco

+0

優れた、非常に包括的な。 +1 – ildjarn

4

あなたはLanguagePrimitivesモジュールから関数を使用することができますを取得したい:

// Convert enum value to the underlying char value 
let ch = LanguagePrimitives.EnumToValue Suit.Clubs 

// Convert the char value back to enum 
let suit = LanguagePrimitives.EnumOfValue ch 

EDIT:私は私の最初の答えの試みで、これらの機能を見ていないので、私が最初に使用した提案:

unbox<char> Suit.Clubs 

これはildjarnコメントで示唆するものよりも短くなっているが、それは同じ問題を抱えています - 実際に正しいタイプに変換しているかどうかの確認はありません。 EnumToValueでは、正しい基底型の値が常に返されるため、間違いを犯すことはできません。別のオプション

type Suit = 
    |Clubs = 'C' 
    |Spades = 'S' 
    |Hearts = 'H' 
    |Diamonds = 'D' 

let c = Suit.Clubs 
let v : char = LanguagePrimitives.EnumToValue c 

として

+2

私は'let ch = char suit'がうまくいかなかったときに驚いた。私は、基になる型への明示的な変換演算子がenumに対して生成されたと仮定していました。 – ildjarn