JsonConvert反序列化SerializeObject生成字符串失败,属性值全为默认值
为什么JsonConvert无法正确反序列化F#结构体?
问题根源
你定义的Point和ObjA结构体中,用val声明的字段默认是私有访问权限,而Json.NET(Newtonsoft.Json)在序列化/反序列化过程中只会处理公共成员。
这就导致调用SerializeObject时,结构体里的id、x、y字段根本没被序列化成JSON内容,最终生成的是一个空的JSON对象{};反序列化时,Json.NET只能创建结构体的默认实例,所有数值字段自然就被设为默认的0或0.0。
可行解决方案
方案1:将字段设为公共
修改结构体定义,给val加上public修饰符,让Json.NET能访问到这些字段:
type Point = struct val public x : float val public y : float new(x, y) = { x = x y = y } end type ObjA = struct val public id : int val public point : Point new (id, point) = { id = id point = point } end
方案2:使用[<CLIMutable>]属性
给结构体添加[<CLIMutable>]属性,这个属性会让F#自动生成公共属性和无参构造函数,完美适配Json.NET这类序列化库:
[<CLIMutable>] type Point = struct val x : float val y : float new(x, y) = { x = x y = y } end [<CLIMutable>] type ObjA = struct val id : int val point : Point new (id, point) = { id = id point = point } end
方案3:改用F#记录类型(推荐)
如果不需要结构体的值类型特性,F#的记录类型默认就支持CLIMutable,序列化反序列化更简洁省心:
type Point = { x : float; y : float } type ObjA = { id : int; point : Point }
使用示例:
let p = { x = 1.9; y = 2.5 } let serializedStr = JsonConvert.SerializeObject({ id = 1; point = p }) let deserializedObj = JsonConvert.DeserializeObject<ObjA>(serializedStr) printfn "ID = %d" deserializedObj.id // 输出1
内容的提问来源于stack exchange,提问作者quincy783
相关产品推荐
相关产品推荐

