使用深度扫描选择器使用 Json.NET 删除 属性 适用于 C#,但在 F# 中抛出 ObjectNullReferenceException

Removing property with Json.NET using deep scan selector works with C# but throws ObjectNullReferenceException in F#

在 netcoreapp3.1 应用程序中使用 json.net 12.0.3,如果用 C# 编写,代码可以正常工作,并且可以在 F# 中使用点表示法,但是一旦我尝试删除找到的元素通过 F# 中的深度扫描选择器,它会抛出一个对象空引用异常。鉴于两者都是 .NET 语言,我的期望是相同的行为。我找不到任何记录在案的差异或行为期望。除了不使用 F#,还有其他可能的资源吗?

示例文档

{
  "Active": true,
    Nested: {
      "Active": true,
    }
}

F# 代码失败

let json = JObject.Parse(File.ReadAllText(@"c:\example.json"))
json.SelectTokens("..Active") 
|> Seq.iter (fun n -> n.Parent.Remove())

后续 C# 代码

var json = JObject.Parse(File.ReadAllText(@"c:\example.json"));
json.SelectTokens("..Active").ToList().ForEach(i => i.Parent.Remove());

我不确定 NRE 的确切来源,但 C# 和 F# 版本之间有一个明显的区别:在 C# 中,您在迭代之前转换为列表,但在 F# 中则不是。尝试这样做:

let json = JObject.Parse(File.ReadAllText(@"c:\example.json"))
json.SelectTokens("..Active") 
|> List.ofSeq
|> List.iter (fun n -> n.Parent.Remove())

我推测当您调用 Remove 时,序列的内容发生变化,在某处产生 null。但是,如果您事先转换为列表,则它是序列的快照,就像在进行任何删除之前一样。