通过一些API,我可以以一系列Gereric.Dictionary的形式访问Table。因为该表有一个模式,我想从中提取记录。这是我的意思?
open System.Collections.Generic
let gd = Dictionary<string,obj> ()
gd.Add("name", "Frank")
gd.Add("age", 24)
gd.Add("born", 1999)
type Person = { name : string
age : int}
let extractPerson (gd:Dictionary<string,obj>) =
{ name = gd.["name"] :?> string
age = gd.["age"] :?> int}
我可以使函数extractPerson
更通用,比如
let extract<'T> (gd:Dictionary<string,obj>) =
// ???
以便我可以打电话?
extract<Person> gd
答案 0 :(得分:5)
正如评论中所提到的,这只能通过反射来完成。以下适用于您的简单示例,但它非常有限:
open Microsoft.FSharp.Reflection
let extract<'T>(gd:Dictionary<string,obj>) =
let flds = FSharpType.GetRecordFields(typeof<'T>)
let vals = [| for f in flds -> gd.[f.Name] |]
FSharpValue.MakeRecord(typeof<'T>, vals) :?> 'T
它使用GetRecordFields
来查找字段的名称,然后从字典中获取它们的值并调用MakeRecord
来创建记录值。这不是超级高效的,但根据你的需要,它可能对你来说足够好。
现在您可以按如下方式使用它:
let gd = Dictionary<string,obj> ()
gd.Add("name", "Frank")
gd.Add("age", 24)
gd.Add("born", 1999)
type Person = { name : string; age : int}
extract<Person> gd