JsonProvider能反序列化为Generic.Dictionary吗?

5

我正在学习类型提供程序,它看起来是一项开创性的功能。但是,我无法使用JsonProvider反序列化具有Generic.Dictionary属性的目标类型的json。可以使用Json.NET完成。以下是代码:

type ByProv = JsonProvider<"""{"dict":{"A":1,"B":2}}""">
type ByHand(d:Dictionary<string,int>) =
    member val dict = d with get,set

let text = """{"dict":{"C":3,"D":4}}"""
let newt = JsonConvert.DeserializeObject<ByHand> text
let prov = ByProv.Parse text
printfn "%A" newt.dict.["C"]
//Can only call statically inferred A or B (and it will throw at run-time)
printfn "%A" prov.Dict.A

显然,默认情况下,dict 被推断为记录类型而不是 Dictionary。这个可以被覆盖吗?

2个回答

5
JSON类型提供程序假定JSON记录用于存储具有固定字段名称的记录,而JSON数组用于存储集合。你的例子是其中一种情况,这种情况并不太适用。
当你需要访问具有动态命名字段的JSON记录时,可以使用提供的类型所公开的底层JsonValue
type ByProv = JsonProvider<"""{"dict":{"A":1,"B":2}}""">

let text = """{"dict":{"C":3,"D":4}}"""
let prov = ByProv.Parse text

prov.Dict.JsonValue.["C"].AsInteger()

我认为这并不是很好,我想JSON类型提供者可以扩展以更好地处理这个问题(并将记录更像数组)。欢迎提交问题进行讨论,也可以提交拉取请求到GitHub上的F#数据


1
如果你想将一个JSON字典转换成.NET字典,可以使用Properties()方法和dict函数,如下所示:
type ByProv = JsonProvider<"""{"dict":{"A":1,"B":2}}""">

let text = """{"dict":{"C":3,"D":4}}"""

let prov = ByProv.Parse text

let d = prov.Dict.JsonValue.Properties() |> dict

d 的类型是 System.Collections.Generic.IDictionary<string,JsonValue>。如果你想让它成为整数,可以在中间使用 Seq.map

let d =
    prov.Dict.JsonValue.Properties()
    |> Seq.map (fun (k,v) -> k,v.AsInteger())
    |> dict

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接