1. ホーム
  2. c#

JContainer、JObject、JTokenとLinqの混乱

2023-10-08 21:12:15

質問

私は、どのような場合に JContainer , JObject そして JToken . 私は、"standards" から、次のように理解しました。 JObject で構成されています。 JProperties であり、その JToken は、すべての JToken の型のための基本抽象クラスですが、私は JContainer .

私はC#を使用しており、LinqPad Pro 5を購入したばかりです。

JSONのデータソースがファイルにあるので、そのファイルの中身をこのステートメントを使ってうまくデシリアライズしています。

string json;
using (StreamReader reader = new StreamReader(@"myjsonfile.json"))
{
    json = reader.ReadToEnd();
}

この時点で、JSON文字列オブジェクトを取り出し、デシリアライズして JObject にデシリアライズします (これは私の間違いかもしれません。 jsonWork a JToken または JContainer ?):

JObject jsonWork = (JObject)JsonConvert.DeserializeObject(json);

私のJSONデータ(JSONで表現された文字列)には、3つのオブジェクトがあります--トップレベルのオブジェクトは、次のようなものです。

{
  "Object1" : { ... },
  "Object2" : { ... },
  "Object3" : { ... }
}

各オブジェクトはあらゆる種類のトークン(配列、文字列、他のオブジェクトなど)で構成されており、動的なJSONになっています。(この質問を多くのJSONデータで混乱させるよりも、プレースホルダーとして省略形を使用しました)。

私は "Object1" , "Object2" そして "Object3" を別々にLINQで実行することができます。なので、理想はこんな感じです。

// these lines DO NOT work    
var jsonObject1 = jsonWork.Children()["Object1"]
var jsonObject2 = jsonWork.Children()["Object2"]
var jsonObject3 = jsonWork.Children()["Object3"]

しかし、上記の行は失敗します。

私は var を使ったのは、どのようなオブジェクトタイプを使うべきか見当がつかないからです。 JContainer , JObject または JToken ! 一応、私がやりたいことは、一旦上記の jsonObject# 変数が適切に割り当てられたら、LINQ を使ってそれらが含む JSON をクエリしたいと思います。以下は非常に簡単な例です。

var query = from p in jsonObject1
   where p.Name == "Name1"
   select p

もちろん、私のLINQは最終的にJSONの配列、オブジェクト、文字列などをフィルタリングするために jsonObject 変数にあるJSON配列をフィルタリングします。一度、LinqPadを使って、LINQを使ったJSONのフィルタリングを手助けしてもらおうと思っています。

を使えばいいことを発見しました。

// this line WORKS 
var jsonObject1 = ((JObject)jsonWork).["Object1"];

それから JObject の中に jsonObject1 . これは正しいアプローチなのでしょうか?

私には、いつ/なぜ JContainer を使うのかが不明です。 JTokenJObject オブジェクトはLINQで非常にうまく動作します。の目的は何でしょうか? JContainer ?

どのように解決するのですか?

JContainer は、子項目を持つJSON要素の基底クラスです。 JObject , JArray , JPropertyJConstructor はすべてこれを継承しています。

例えば、次のようなコードです。

(JObject)JsonConvert.DeserializeObject("[1, 2, 3]")

を投げます。 InvalidCastException を投げますが、これを JContainer にキャストすれば、問題ないでしょう。

最初の質問についてですが、トップレベルにJSONオブジェクトがあることが分かっている場合は、そのまま使えます。

var jsonWork = JObject.Parse(json);
var jsonObject1 = jsonWork["Object1"];