我的F#代碼的某些功能接收到的值作爲對象裝箱,即使底層值是鍵入的。如果這個值是一個有區別的聯合,那麼就不可能將它重新裝回到它的F#類型中。下面是一個簡單的例子:F#歧視工會的拆箱價值
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"
從這個例子的輸出爲「經由反射匹配」,ResultA永遠沒有匹配,因爲已裝箱值是不同的CLR類型的 - Result.Ok。由於F#歧義聯合事例被表示爲其自己的類型,因此裝箱值與ResultA類型不匹配。此外,無法將它與ResultA.OK匹配,因爲在F#代碼中它不是合法類型。唯一的選擇似乎是使用反射手動實例化一個值,這是低效率和愚蠢的,因爲該值已經實例化,它就在這裏,一旦它被裝箱,它就無法在F#代碼中被訪問。
我可以俯視嗎?有沒有更直接的方式拆箱F#歧視聯合價值?
感謝Fyodor。其實你的第一個建議沒有奏效 - 使變量正確的類型明確地導致了相同的盒裝類型並且不匹配。但第二個工作 - 改變模式匹配的情況。 –
您在嘗試第一個選項時一定犯了錯誤。它確實有效。 –
我完全同意你的預防措施。不幸的是,由於外部庫的細節,我必須處理幾個盒裝值。 –