繁体   English   中英

F#:如何使用 Newtonsoft.Json 反序列化私有歧视联合?

[英]F#: How to deserialize a private discriminated union with Newtonsoft.Json?

2018 年的问答中Onur Gumus使用 [<JsonObject(MemberSerialization = MemberSerialization.Fields)>] 来启用具有私有构造函数的可区分联合的序列化/反序列化。

"对我来说,序列化如宣传的那样工作,但反序列化会产生以下错误:“

有谁知道如何让反序列化工作? 如果可以避免,我不想切换到类类型。 但是,我已经尝试找出放置 JsonConstructor 属性的位置,但没有任何运气。 我还尝试传递一个ConstructorHandling值设置为 AllowNonPublicDefaultConstructor 的设置值,但这没有任何改变。

为方便起见,我在这里复制 Onur 的解决方案:

open Newtonsoft.Json
[<JsonObject(MemberSerialization = MemberSerialization.Fields)>]
type Foo =  private Bar of string
let f = Bar "f"
let s = JsonConvert.SerializeObject(f)
let f2 = JsonConvert.DeserializeObject<Foo>(s)

printf "%A" f2

万一重要(因为自 2018 年以来事情似乎发生了变化),我正在使用 .NET 5。

我有理由确定你偶然发现了一个错误。

当我将您引用的示例代码复制到 LINQPad v6.13.13 中并运行时,它运行良好。 然后我尝试用另一个属性替换该属性 - 我在评论中提到的那个。 没想到没有编译。 所以我只是恢复到原来的属性。 然后我遇到了与您遇到的相同的编译错误。 那不应该发生。 这是一个错误。 但是哪里?

进一步调查显示,如果我在 LINQPad 中执行以下操作,则会错误地产生编译错误:

  1. 从文件中打开代码片段,然后尝试运行它。 这编译并运行良好。
  2. 注释掉该属性,然后尝试运行它。 这会产生有问题的编译错误。 这是应该的。
  3. 带回属性,并尝试运行它。 这当然应该编译并运行良好,因为源现在与步骤 1 中的一样,但它仍然会产生有问题的编译错误。

重复尝试相同的步骤会产生相同的问题,无论我是否在两次运行之间重新启动 LINQPad。

然后我尝试用 Visual Studio 重现这个问题。 我没有成功 - 在 VS 16.10.3 中没有这样的问题

我现在没有更多时间,但稍后会继续调查。 我想用最新的 LINQPad 测试版来检查一下。

至于你的问题,是这个原因吗?

更新

我现在已经检查了当前的测试版 LINQPad v6.14.10。 该错误不存在于那里。 我并不感到意外。 正如我在评论中提到的,编译器是我的主要嫌疑人。 更是如此,因为你告诉你 VSCode 有问题。 但还有一个更有趣的细节。

LINQPad 使用一个非常旧版本的 F# 编译器服务已经有很长时间了,因为有一个错误阻止了它的更新。 LINQPad 的创建者 Joseph Albahari 最近迫不及待地等待修复此错误,并找到了解决方法。 该修复程序仅在测试版中。 F# 编译器服务版本的巨大飞跃自然意味着许多错误已得到修复,很可能也是这个错误。

我不打算进一步探讨这个问题。 我不使用 VSCode,但如果即使在最新的 REPL 中也存在这个问题,那么也许有人应该调查一下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM