F#コードの一部の関数は、基になる値が入力されてもオブジェクトとしてボックス化された値を受け取ります。値が識別された共用体の場合、そのF#型に戻すことはできません。ここでは簡単な例である: - Result.OkF#の値をアンボックスすると、ユニオンが識別されます
type Result<'TOk,'TError> =
| Ok of 'TOk
| Error of 'TError
type ResultA = Result<string, int>
let a = Ok "A"
let o = box a
match o with
| :? ResultA -> printfn "match ResultA"
// | :? ResultA.Ok -> printfn "match" // doesn't compile
| _ when o.GetType().DeclaringType = typedefof<ResultA> -> printfn "match via reflection"
| _ -> printfn "no match"
この例からの出力は、箱入りの値が異なるCLR型であるため、ResultAが一致したことはありません、「リフレクション経由一致」です。 F#識別された共用体のケースは、それ自身の型として表現されるので、ボックス化された値は型ResultAと一致しません。さらに、F#コード内では合法的な型ではないため、ResultA.OKと一致させることはできません。唯一のオプションは、値がすでにインスタンス化されているため、非効率的で愚かなリフレクションを使用した値の手動インスタンス化のようです。ここでは、F#コードでは一度アクセスできません。
私は何か見落としていますか? F#で識別されたユニオン値をアンボックスするより簡単な方法はありますか?
ありがとうFyodor。実際にあなたの最初の提案はうまくいかなかった - 変数を明示的に正しいボックス型にし、一致しなかった変数を作成する。しかし、2番目の方法では、パターンマッチングのケースを変更しました。 –
最初のオプションを試してみるには間違いがあります。それは動作します。 –
あなたの予防措置に私は完全に同意します。残念ながら、私は外部ライブラリの特性のためにいくつかの値を扱わなければなりません。 –