如何在F#中获取给定联合类型的每个联合案例的类型 [英] How to get the type of each union case for a given union type in 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 PropertyInfo
s 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"等.可以从PropertyInfo
的PropertyType
属性中检索字段类型本身,因此:
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屋!