如何使 Newtonsoft.Json.Linq.JObject 不可变?

Posted

技术标签:

【中文标题】如何使 Newtonsoft.Json.Linq.JObject 不可变?【英文标题】:How to make Newtonsoft.Json.Linq.JObject immutable? 【发布时间】:2016-01-28 16:32:22 【问题描述】:

我可以创建 JObject

var jobject = Newtonsoft.Json.Linq.JObject.Parse(jsonstring);

我想将 jobject 转换为只读,这样就不能添加新键或修改现有值。

【问题讨论】:

jobject的范围是什么? C# public variable as writeable inside the class but readonly outside the class 对你有用吗? @AndrewMorton 我不控制 JObject 类。我可以在它周围写一个包装器,但它不会是微不足道的。 您不需要更改 JObject 类,只需控制对该 jobject 实例的访问即可。或者您是说 所有 JObject 实例必须是只读的? @AndrewMorton 不是全部,但我不明白如何在不编写包装类的情况下控制访问。 您可以在JObject.PropertyChangingJContainer.ListChanged 中抛出异常,但后者发生在更改之后,因此为时已晚。 【参考方案1】:

这是不可能的。实现它有一个未解决的问题:

https://github.com/JamesNK/Newtonsoft.Json/issues/468

但据我所知,它已经两岁了,几乎没有引起人们的注意。

【讨论】:

【参考方案2】:

不可变对象是无法更改的。如果您不希望 JObject 的消费者更改它,只需给他们一份副本。 (注:本例使用JObject的抽象超类JToken提供更通用的解决方案。)

private JToken data = JToken.Parse(@"""Some"":""JSON""");

public JToken Data()

   return data.DeepClone();


public JToken Data(string path)

   return data.SelectToken(path).DeepClone();

消费者将能够更改他们的副本,但不能更改来源。

如果data 太大以至于无法克隆它,请使用第二种方法JToken Data(string path) 获取子集。

【讨论】:

以上是关于如何使 Newtonsoft.Json.Linq.JObject 不可变?的主要内容,如果未能解决你的问题,请参考以下文章

如何”Newtonsoft.Json.Linq.JValue”的对象强制转换为类型“Newtonsoft.Json.Linq.JArray"?

无法将类型“newtonsoft.json.linq.jtoken”隐式转换为 newt“newtonsoft.json.linq.jvalue”

从 JSON 检索项目时获取“无法将 Newtonsoft.Json.Linq.JObject 转换为 Newtonsoft.Json.Linq.JToken”

无法将“Newtonsoft.Json.Linq.JObject”类型的对象强制转换为“Newtonsoft.Json.Linq.JArray”

JsonResult(object) 导致“不支持集合类型'Newtonsoft.Json.Linq.JToken'。”

将 Newtonsoft.Json.Linq.JArray 转换为特定对象类型的列表