F# 如何从通用词典中提取记录?
通过一些API,我可以以Gereric.Dictionary序列的形式访问这类表。因为表有一个模式,所以我想从中提取记录。这是我的东西F# 如何从通用词典中提取记录?,f#,F#,通过一些API,我可以以Gereric.Dictionary序列的形式访问这类表。因为表有一个模式,所以我想从中提取记录。这是我的东西 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
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}
这样我就可以打电话了
extract<Person> gd
提取gd
正如评论中所提到的,这只能通过反射来实现。以下内容适用于您的简单示例,但非常有限:
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
正如在评论中提到的,这只能通过反射来实现。以下内容适用于您的简单示例,但非常有限:
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
如何
extract是的,只需使用字典中的匹配键填充记录就可以了。f#是静态键入的,因此您必须使用反射或to之类的方法来实现这一点。如果您知道编译时的键列表,您可以查看代码生成或类型提供程序(但我怀疑是否有现成的提供程序)。假设'T
必须是一条记录,我会尝试通过对'T
中的所有字段进行反射来解决它,从dict中读取字段,在对象数组中收集它们,然后您必须调用记录构造函数。如果你的'T
没有可设置的属性,事情就容易多了。如何提取是的,只要用字典中匹配的键填充记录就可以了。f#是静态键入的,因此你必须使用反射或to之类的方法来实现这一点。如果您知道编译时的键列表,您可以查看代码生成或类型提供程序(但我怀疑是否有现成的提供程序)。假设'T
必须是一条记录,我会尝试通过对'T
中的所有字段进行反射来解决它,从dict中读取字段,在对象数组中收集它们,然后您必须调用记录构造函数。如果您的'T
具有可设置的属性,事情会变得更容易。谢谢您的帮助。对我来说,这似乎适用于所有记录类型,你的意思是根据性能进行限制吗?我认为这是有限的,因为可能需要更多的功能来实现这一点-嵌套记录如何?如果值是int
,但您的记录需要浮点值
,该怎么办?等等。但对于基本的,这是成功的。谢谢你这么大的帮助。对我来说,这似乎适用于所有记录类型,你的意思是根据性能进行限制吗?我认为这是有限的,因为可能需要更多的功能来实现这一点-嵌套记录如何?如果值是int
,但您的记录需要浮点值
,该怎么办?等等。但对于基本情况来说,这就是诀窍。
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