How to get the type of each union case for a given union type in F#

僤鯓⒐⒋嵵緔 提交于 2019-12-11 07:46:54

问题


I am wondering in the F# code below how to fetch the type associated with each union case via reflection

type AccountCreatedArgs = {
    Owner: string
    AccountId: Guid
    CreatedAt: DateTimeOffset
    StartingBalance: decimal
}

type Transaction = {
    To: Guid
    From: Guid
    Description: string
    Time: DateTimeOffset
    Amount: decimal
}

type AccountEvents =
    | AccountCreated of AccountCreatedArgs
    | AccountCredited of Transaction
    | AccountDebited of Transaction

I tried using FSharpType.GetUnionCases(typeof<AccountEvents>) but UnionCaseInfo does not provide any information about the case type (only the declaring type aka AccountEvents so not really useful in my case) =/


The answer of glennsl really helped me https://stackoverflow.com/a/56351231/4636721

What I really found handy in my case was:

let getUnionCasesTypes<'T> =
    Reflection.FSharpType.GetUnionCases(typeof<'T>)
    |> Seq.map (fun x -> x.GetFields().[0].DeclaringType)

回答1:


UnionCaseInfo has a GetFields method which returns an array of PropertyInfos which describe each field/argument of the union case. For example:

FSharpType.GetUnionCases(typeof<AccountEvents>)
    |> Array.map(fun c -> (c.Name, c.GetFields()))
    |> printfn "%A"

will print

[|("AccountCreated", [|AccountCreatedArgs Item|]);
  ("AccountCredited", [|Transaction Item|]);
  ("AccountDebited", [|Transaction Item|])|]

The name assigned to a single field union case is "Item", and if multiple is "Item1", "Item2" etc. The field type itself can be retrieved from the PropertyType property of PropertyInfo, so:

FSharpType.GetUnionCases(typeof<AccountEvents>)
    |> Array.map(fun c -> (c.Name, c.GetFields() |> Array.map(fun p -> p.PropertyType.Name)))
    |> printfn "%A"

will thus print

[|("AccountCreated", [|"AccountCreatedArgs"|]);
  ("AccountCredited", [|"Transaction"|]);
  ("AccountDebited", [|"Transaction"|])|]


来源:https://stackoverflow.com/questions/56350576/how-to-get-the-type-of-each-union-case-for-a-given-union-type-in-f

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!