如何在F#中获取给定联合类型的每个联合案例的类型

时间:2019-05-28 22:01:09

标签: reflection types f# discriminated-union

我想知道下面的F#代码中如何通过反射来获取与每个联合案例关联的类型

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

我尝试使用FSharpType.GetUnionCases(typeof<AccountEvents>),但是UnionCaseInfo没有提供有关案例类型的任何信息(仅声明类型,也称为AccountEvents,因此在我的案例中并不真正有用)= /

1 个答案:

答案 0 :(得分:4)

UnionCaseInfo有一个GetFields方法,该方法返回一个PropertyInfo数组,这些数组描述联合案例的每个字段/参数。例如:

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

将打印

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

分配给单个字段联合用例的名称为“ Item”,如果为多个则为“ Item1”,“ Item2”等。可以从{{1}的PropertyType属性中检索字段类型本身},所以:

PropertyInfo

因此将打印

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