本文介绍了JToken不是JObject的引用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还没有注意到James Newton King撰写或谈论了JToken .我做出了一个错误的假设,即它以某种方式保留了对JObject的引用.这些LINQPad语句演示的情况并非如此:

I have not yet noticed that James Newton King wrote or spoke about what JToken is. I have made the incorrect assumption that it somehow holds a reference to JObject. This is not the case as the these LINQPad statements demonstrate:

var json = @"
{
    ""item"": {
        ""foo"": ""4"",
        ""bar"": ""42""
    }
}
";

var jO = JObject.Parse(json);
var jToken = jO["item"]["foo"];

jToken = "5";

jO.ToString().Dump("jO");

jToken.Dump("jToken");

输出:

jO
{
  "item": {
    "foo": "4",
    "bar": "42"
  }
}

jToken
5

应该jO["item"]["foo"] == 5吗?

推荐答案

首先,让我们谈谈 JToken 是.

First, let's talk about what a JToken is.

  • JTokenJObjectJArrayJPropertyJValue的抽象基类.
  • JObjectJProperty对象的集合. JObject不能容纳任何其他种类的JToken.
  • JProperty是一个名称/值对.名称始终是一个字符串,值可以是任何JToken,除了另一个JProperty.
  • JArray是除JProperty之外的任何类型的JToken对象的数组.
  • JValue表示JSON基本值.它可以包含字符串,数字,布尔值,日期或null.请注意,JValue是与所有其他JTokens一样的引用类型.
  • JToken is the abstract base class for JObject, JArray, JProperty and JValue.
  • JObject is a collection of JProperty objects. A JObject cannot hold any other kind of JToken.
  • JProperty is a name-value pair. The name is always a string, and the value can be any kind of JToken except another JProperty.
  • JArray is an array of JToken objects of any kind except JProperty.
  • JValue represents a JSON primitive value. It can contain a string, number, boolean, date or null. Note that JValue is a reference type like all other JTokens.

上述类旨在为 JSON规范建模.

现在让我们谈谈您在做什么以及感到困惑的地方.

Now let's talk about what you're doing and where you're getting confused.

在您的代码中,您首先要创建一个JObject. JObject包含一个称为item的JProperty. item的值是另一个JObject,它包含两个JProperty,分别称为foobar.这些JProperty的值都是包含字符串的JValue(分别为442).

In your code, you are first creating a JObject. The JObject contains one JProperty called item. The value of item is another JObject which contains two JProperties, called foo and bar. The values of these JProperties are both JValues containing strings (4 and 42, respectively).

接下来,您使用JToken索引器语法获取对foo JProperty的 value 的引用(一个包含字符串值4的JValue),并将该引用分配给您的jToken变量.请注意,此变量的声明类型为JToken,即使该值的实际类型实际上是JValue. (如果您执行jToken.GetType().Name.Dump("jToken type"),则可以看到此内容)

Next, you use the JToken indexer syntax to get a reference to the value of the foo JProperty (a JValue which contains the string value 4) and assign that reference to your jToken variable. Note the declared type of this variable is JToken, even though the actual type of the value here is in fact JValue. (You can see this if you do jToken.GetType().Name.Dump("jToken type") )

到目前为止和我在一起吗?

With me so far?

好的,这是我认为您感到困惑的地方. JToken提供隐式和显式转换,从而允许将其从各种.NET原语分配或强制转换为各种.NET原语.如果您执行jToken = "5",则实际上与jToken = new JValue("5")含义相同.因此,您要做的是用对另一个包含5的JValue的新引用替换您的jToken变量具有的引用(对包含4的JValue).这显然不会对原始JObject产生影响.

OK, here is where I think you are getting confused. JToken provides implicit and explicit conversions which allow it to be assigned from or cast to various .NET primitives. If you do jToken = "5" that really means the same thing as jToken = new JValue("5"). So what you have done is to replace the reference that your jToken variable had (to the JValue containing 4) with a new reference to a different JValue containing 5. This obviously will have no effect on the original JObject.

如果尝试修改原始JValue的值,则需要将jToken强制转换为JValue,然后使用Value设置器进行设置.

If you are trying to modify the value of the original JValue, you need to cast your jToken to JValue and then use the Value setter to set it.

((JValue)jToken).Value = "5";

提琴: https://dotnetfiddle.net/StIGxM

这篇关于JToken不是JObject的引用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-13 06:12