Eho*_*ret 2 reflection f# types 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
Run Code Online (Sandbox Code Playgroud)
我尝试使用FSharpType.GetUnionCases(typeof<AccountEvents>)但UnionCaseInfo没有提供任何关于案例类型的信息(只有声明类型,AccountEvents所以在我的案例中并不是真的有用)=/
glennsl 的回答真的帮助了我/sf/answers/3944586201/
在我的案例中,我真正觉得很方便的是:
let getUnionCasesTypes<'T> =
Reflection.FSharpType.GetUnionCases(typeof<'T>)
|> Seq.map (fun x -> x.GetFields().[0].DeclaringType)
Run Code Online (Sandbox Code Playgroud)
UnionCaseInfo有一个GetFields方法,它返回一个PropertyInfos数组,它描述了联合案例的每个字段/参数。例如:
FSharpType.GetUnionCases(typeof<AccountEvents>)
|> Array.map(fun c -> (c.Name, c.GetFields()))
|> printfn "%A"
Run Code Online (Sandbox Code Playgroud)
将打印
[|("AccountCreated", [|AccountCreatedArgs Item|]);
("AccountCredited", [|Transaction Item|]);
("AccountDebited", [|Transaction Item|])|]
Run Code Online (Sandbox Code Playgroud)
分配给单个字段联合大小写的名称是“Item”,如果多个是“Item1”、“Item2”等。字段类型本身可以从 的PropertyType属性中检索PropertyInfo,因此:
FSharpType.GetUnionCases(typeof<AccountEvents>)
|> Array.map(fun c -> (c.Name, c.GetFields() |> Array.map(fun p -> p.PropertyType.Name)))
|> printfn "%A"
Run Code Online (Sandbox Code Playgroud)
将因此打印
[|("AccountCreated", [|"AccountCreatedArgs"|]);
("AccountCredited", [|"Transaction"|]);
("AccountDebited", [|"Transaction"|])|]
Run Code Online (Sandbox Code Playgroud)