您尝试改变的序列化器设置,Compact.TupleAsArraySettings.settings
, is a 静态成员,如图所示code https://github.com/microsoft/fsharplu/blob/master/FSharpLu.Json/Compact.fs#L338:
type TupleAsArraySettings =
static member formatting = Formatting.Indented
static member settings =
JsonSerializerSettings(
NullValueHandling = NullValueHandling.Ignore,
// MissingMemberHandling is not technically needed for
// compact serialization but it avoids certain ambiguities
// that guarantee that deserialization coincides with the
// default Json.Net deserialization.
// (where 'coincides' means 'if the deserialization succeeds they both return the same object')
// This allows us to easily define the BackwardCompatible
// serializer (that handles both Compact and Default Json format) by reusing
// the Compact deserializer.
MissingMemberHandling = MissingMemberHandling.Error,
Converters = [| CompactUnionJsonConverter(true, true) |]
)
Since a member
实际上是一个成员函数(即方法)正如所解释的F# 的乐趣和利润:将函数附加到类型 https://fsharpforfunandprofit.com/posts/type-extensions/, settings
实际上(用 C# 术语来说)是一个返回新实例的静态属性JsonSerializerSettings
每次调用它时。为了测试这一点,我们可以这样做:
printfn "%b" (Object.ReferenceEquals(Compact.TupleAsArraySettings.settings, Compact.TupleAsArraySettings.settings)) // prints "false"
打印“假”。因此改变返回值对行为没有影响Compact
。 C# 意义上的静态字段将由static let
陈述;如果settings
返回这样一个字段,改变它的内容就会产生效果。
在任何情况下修改的值Compact.TupleAsArraySettings.settings.MissingMemberHandling
似乎不明智,因为这样做会改变 of 的行为Compact.deserialize
以一种可能会破坏的方式贯穿整个 AppDomain向后兼容性 https://github.com/Microsoft/fsharplu/wiki/fsharplu.json#backward-compatibility-with-jsonnet使用 Json.NET 本机序列化。正如上面代码注释中所解释的,需要进行设置BackwardCompatible.deserialize https://github.com/microsoft/fsharplu/blob/master/FSharpLu.Json/BackwardCompatible.fs#L50工作。但为什么会这样呢?由于 Json.NET 的本机格式为option
受歧视的工会看起来像:
{
"a": {
"Case": "Some",
"Fields": [
3
]
}
}
我们可以猜测MissingMemberHandling
用于捕获以下情况"Case"
and "Fields"
是否找到,并从一种算法切换到另一种算法。
如果您确定不需要以 Json.NET 格式反序列化 f# 类型,看来你应该能够使用CompactUnionJsonConverter https://github.com/microsoft/fsharplu/blob/master/FSharpLu.Json/Compact.fs#L77直接如下:
let settings = JsonSerializerSettings(
NullValueHandling = NullValueHandling.Ignore,
Converters = [| CompactUnionJsonConverter(true, true) |]
)
let c = JsonConvert.DeserializeObject<r>(a, settings)
let json2 = JsonConvert.SerializeObject(c, Formatting.Indented, settings)
演示小提琴here https://dotnetfiddle.net/FFpG52.