首页 > 解决方案 > 为什么 Newtonsoft 在 F# 中将缺少的整数字段转换为其默认值?

问题描述

在 F# 中使用 Newtonsoft 反序列化 JSON 对象时,我注意到反序列化过程会将缺失的整数字段转换为其默认值。在以下示例中,缺失的整数字段instanceB将转换为具有默认值 ( 0) 的整数字段。但是当缺少的字段NameinstanceC(类型为string)时,它会转换为null. 为什么反序列化的输出会根据字段的类型而有所不同?

#r """Newtonsoft.Json.dll"""

open Newtonsoft.Json

type Test = {
    Id:   int
    Name: string
}

let instanceA = """{"Id": 1, "Name": "A"}"""
let instanceB = """{"Name": "A"}"""
let instanceC = """{"Id": 1}"""

let A = JsonConvert.DeserializeObject<Test>(instanceA)
let B = JsonConvert.DeserializeObject<Test>(instanceB)
let C = JsonConvert.DeserializeObject<Test>(instanceC)

printfn "%A" A
printfn "%A" B
printfn "%A" C

输出:

val A : Test = { Id = 1
                 Name = "A" }
val B : Test = { Id = 0
                 Name = "A" }
val C : Test = { Id = 1
                 Name = null }

标签: jsonf#json.netjson-deserialization

解决方案


在 .NET 中,有些类型具有null可能的值,而有些则没有。后者称为“值类型”,前者称为“引用类型”。

int是一个值类型,所以它不能是null.

string是引用类型,所以它可以。

不过,每种类型都有一个默认值。对于引用类型,默认值为null。对于值类型,它取决于类型,但通常是零的一些变化。所以这些就是你得到的价值。


推荐阅读