JToken不是局限性的参考



我尚未注意到詹姆斯·牛顿·金(James Newton King)撰写或谈到了 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");

输出:

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

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

首先,让我们谈谈 JToken是什么。

  • JTokenJObjectJArrayJPropertyJValue的抽象基类。
  • JObjectJProperty对象的集合。JObject不能容纳任何其他类型的JToken
  • JProperty是名称值对。该名称始终是字符串,该值可以是任何类型的JToken,除另一个JProperty
  • JArrayJToken的一个数组,除JProperty外,任何种类的对象
  • JValue代表JSON原始值。它可以包含一个字符串,数字,布尔值,日期或null。请注意,JValue是类型类型,就像所有其他Jtokens一样。

上面的类旨在建模JSON规格

现在让我们谈谈您在做什么以及您在哪里感到困惑。

在您的代码中,您首先创建了一个职位。该职位包含一个称为item的Jproperty。item的值是另一个包含两个Jproperties的锻炼,称为foobar。这些Jproperties的值既包含字符串(分别为442)。

接下来,您使用jtoken索引语法获取foo Jproperty的 value 的引用(包含字符串值4的JVALUE),并将该引用分配给您的jToken变量。请注意,该变量的声明类型是jtoken的,即使此处值的实际类型实际上是JVALUE。(如果您执行jToken.GetType().Name.Dump("jToken type"),可以看到这一点)

到目前为止和我在一起?

好吧,这是我认为您感到困惑的地方。Jtoken提供了隐式和明确的转换,可以将其从分配或投入到各种.NET原始词。如果您执行jToken = "5",那确实与jToken = new JValue("5")相同。因此,您所做的是用新的参考jToken变量(到包含4的JVALUE)的引用,并使用对包含5的不同JVALUE的新引用。显然,这将对原始局面没有影响。

如果您要修改原始JValue的值,则需要将jToken投射到JValue,然后使用Value设置器将其设置为设置。

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

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

实际上JToken具有其父(检查Parent属性)。
返回您的示例 - 在此行jToken = "5";中,您正在创建新的JToken(更具体地说,字符串被隐式转换为JValue)。基本上,它与jToken = new JValue("5");相同,因此可变jToken现在指向全新的JValue。这解释了为什么更改未反映在原始JObject中。
要修复您的示例:((JValue)jToken).Value = "5";

相关内容

  • 没有找到相关文章

最新更新