Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 如何从通用词典中提取记录?_F# - Fatal编程技术网

F# 如何从通用词典中提取记录?

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

通过一些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
                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