JToken不是JObject的参考?

ras*_*asx 2 json.net linqpad

我还没有注意到,詹姆斯·牛顿写的国王或者谈到什么JToken .我做了一个错误的假设,它以某种方式持有一个参考JObject.情况并非如此,因为这些LINQPad语句演示了:

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");
Run Code Online (Sandbox Code Playgroud)

输出:

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

jToken
5 
Run Code Online (Sandbox Code Playgroud)

不应该jO["item"]["foo"] == 5

Bri*_*ers 10

首先,我们来谈谈它是什么JToken.

  • JToken对于抽象基类JObject,JArray,JPropertyJValue.
  • JObject是一个JProperty对象的集合.A JObject不能容纳任何其他类型的JToken.
  • JProperty是一个名称 - 值对.名称始终是一个字符串,值可以是JToken除另一个之外的任何类型JProperty.
  • JArrayJToken除了之外的任何类型的对象数组JProperty.
  • JValue表示JSON原始值.它可以包含字符串,数字,布尔值,日期或null.请注意,这JValue是一个像所有其他JTokens一样的引用类型.

上述类旨在模拟JSON规范.

现在让我们谈谈你正在做什么以及你在哪里感到困惑.

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

接下来,您使用JToken索引语法去的一个参考中的fooJProperty(其中包含字符串值JValue 4)并分配引用您的jToken变量.注意这个变量的声明类型是JToken,即使这里的值的实际类型实际上是JValue.(你可以看到这个jToken.GetType().Name.Dump("jToken type"))

和我一起到目前为止?

好的,这是我认为你感到困惑的地方.JToken提供隐式和显式转换,允许从各种.NET原语进行分配或转换.如果你那样做jToken = "5"真的意味着同样的事情jToken = new JValue("5").所以你所做的就是用一个包含不同JValue的新引用替换你的jToken变量(包含JValue 4)的引用5.这显然对原始的JObject没有影响.

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

((JValue)jToken).Value = "5";
Run Code Online (Sandbox Code Playgroud)

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