如何在F#中获取给定联合类型的每个联合案例的类型 [英] How to get the type of each union case for a given union type in F#

查看:94
本文介绍了如何在F#中获取给定联合类型的每个联合案例的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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) =/

glennsl的回答确实帮助了我 https://stackoverflow.com/a/56351231/4636721

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

我真正感到方便的是:

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

推荐答案

UnionCaseInfo有一个GetFields方法,该方法返回一个描述了联合用例的每个字段/参数的PropertyInfo s数组.例如:

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"

将打印

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

分配给单个字段联合用例的名称为"Item",如果为多个则为"Item1","Item2"等.可以从PropertyInfoPropertyType属性中检索字段类型本身,因此:

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"

因此将打印

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

这篇关于如何在F#中获取给定联合类型的每个联合案例的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆