Json   发布时间:2022-04-22  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了通过Json.Net反序列化F#Map大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个简单的问题:是否可以从 json解析F#Map类型?因为当我尝试它时(使用F#Map< String,String>),它很容易序列化并且它看起来如何,但是当我尝试反序列化时它会引发异常.

@H_419_11@Newtonsoft.Json.JsonserializationException: Unable to find a default constructor to use for type Microsoft.FSharp.Collections.FSharpMap`2[system.int32,System.String]. Path '1',line 2,position 7. at Newtonsoft.Json.serialization.JsonserializerInternalReader.CreateNewDictionary (Newtonsoft.Json.JsonReader reader,Newtonsoft.Json.serialization.JsonDictionaryContract contract,System.Boolean& createdFromNonDefaultConstructor) [0x00000] in <filename unkNown>:0 at Newtonsoft.Json.serialization.JsonserializerInternalReader.CreateObject (Newtonsoft.Json.JsonReader reader,System.Type objectType,Newtonsoft.Json.serialization.JsonContract contract,Newtonsoft.Json.serialization.JsonProperty member,Newtonsoft.Json.serialization.JsonContainerContract containerContract,Newtonsoft.Json.serialization.JsonProperty containerMember,System.object exisTingvalue) [0x00000] in <filename unkNown>:0 at Newtonsoft.Json.serialization.JsonserializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader,System.object exisTingvalue) [0x00000] in <filename unkNown>:0 at Newtonsoft.Json.serialization.JsonserializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader,Boolean checkAdditionalContent) [0x00000] in <filename unkNown>:0

它是经典的反序列化:

@H_419_11@map.ofList [ ("1","one"); ("2","two"); ("3","three") ]

生成的JSON看起来像C#字典

@H_419_11@{ "1": "one","2": "two","3": "three" }

它没有设置序列化(只有缩进).那么可以序列化这个,还是有一些可行的解决方法

谢谢你的回答

解决方法

您可以制作自己的转换器来执行此操作.这是很多反思和构建适当的泛型类型,但它可以完成.

首先反序列化为Dictionary< Key,Val>,然后创建并填充List< Tuple< Key,Val>>通过反射手动(因为Map构造函数需要Tuples,而不是KeyValuePairs),然后最终将它传递给Map构造函数.

不确定是否有更简单的方法,但这是我提出的:

@H_419_11@open System open System.Collections open System.Collections.Generic open Newtonsoft.Json let mapConverter = { new JsonConverter() with override x.CanConvert(t:TypE) = t.IsGenericType && t.GetGenericTypeDeFinition() = typedefof<Map<_,_>> override x.WriteJson(writer,value,serializer) = serializer.serialize(writer,value) override x.ReadJson(reader,t,_,serializer) = let genArgs = t.GetGenericArguments() let generify (t:TypE) = t.MakeGenericType genArgs let tupleType = generify typedefof<Tuple<_,_>> let listType = typedefof<List<_>>.MakeGenericType tupleType let create (t:TypE) types = (t.GetConstructor types).Invoke let list = create listType [||] [||] :?> IList let kvpType = generify typedefof<KeyValuePair<_,_>> for kvp in serializer.Deserialize(reader,generify typedefof<Dictionary<_,_>>) :?> IEnumerable do let get name = (kvpType.GetProperty Name).GetValue(kvp,null) list.Add (create tupleType genArgs [|get "Key"; get "Value"|]) |> ignore create (generify typedefof<Map<_,_>>) [|listType|] [|list|] }

一旦你有了转换器,那么你只需将它传递给DeserializeObject方法,JsonConvert将在适当的地方使用它.

@H_419_11@let str = JsonConvert.serializeObject (Map<_,_> [333,1234]) JsonConvert.DeserializeObject<Map<int,int>>(str,mapConverter)

这样做的好处是,如果你有一个很大/很深的记录,你的Map只是一个字段,那么它也可以使用它 – 你不必改变你的记录结构使用词典只是为了支持序列化.

大佬总结

以上是大佬教程为你收集整理的通过Json.Net反序列化F#Map全部内容,希望文章能够帮你解决通过Json.Net反序列化F#Map所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。