2013-10-05 4 views
2

Я извиняюсь за возможно глупый вопрос, но ...Зачем мне нужно звонить. First() в foreach/Select() в Json.Net?

У меня есть следующие JSON (упрощенный, очевидно):

 
{ 
    "rgDescriptions":{ 
     "32895951_0":{ 
     "id":"32895951", 
     "name":"Cat", 
     }, 
     "61694787_0":{ 
     "id":"61694787", 
     "name":"Dog", 
     } 
    } 
} 

В качестве простого примера моей проблемы, это работает:

jsonObject["rgDescriptions"]["32895951_0"]["name"] 

Но это вовсе не так:

jsonObject["rgDescriptions"].First()["name"] 
//InvalidOperationException: Cannot access child value on Newtonsoft.Json.Linq.JProperty. 

Для того, чтобы заставить его работать, мне нужно, чтобы изменить его к этому:

jsonObject["rgDescriptions"].First().First()["name"] 

Это не имеет никакого смысла для меня, так как первый объект в jsonObject["rgDescriptions"] должно быть эквивалентно ["32895951_0"]. Оператор [] и .First() возвращают JToken, поэтому я действительно не понимаю, почему ["rgDescriptions"].First() не работает или что он действительно должен представлять.

Может ли кто-нибудь объяснить мне, что происходит?

ответ

3

Сначала было бы полезно пересмотреть, что такое JToken и что он может содержать.

  • JToken является абстрактным базовым классом для JObject, JProperty, JArray и JValue. Все они представляют собой конструкции, которые могут отображаться в JSON.
  • A JObject - это коллекция JProperty объектов. Он не может содержать ничего другого.
  • A JProperty - по существу пара ключей. Он имеет Name, который является строкой, и Value, который является еще одним JToken, который не является JProperty.

Имея это в виду, мы можем ответить на вопрос.

JObject["key"] находит JProperty в JObject с заданным ключом и возвращает JToken, который является Value частью JProperty (или нулевое значение, если ключ не найден).

JToken.First возвращает первый ребенок данного JToken. Для JObject первым ребенком является JProperty (а не Value of JProperty). Для JProperty первым (и единственным) дочерним является ValueJProperty.

Почему они не работают одинаково?

Ну, если метод JObject["key"] вернул JProperty, а не его значение, то вы не смогли бы сделать jsonObject["key1"]["key2"]["key3"]. Вместо этого вам придется использовать более громоздкий синтаксис jsonObject["key1"].Value["key2"].Value["key3"].

И наоборот, если JToken.First всегда возвращается в Value из JProperty, то вы никогда не сможете использовать его, чтобы открыть Name в JProperty. (Если вы используете этот метод, предположительно, вы еще не знаете имя свойства, тогда как если вы используете другой метод, вы его знаете.) Кроме того, свойства навигации, такие как Next, Prev и т. Д., Не будут работайте правильно, потому что вы были бы на неправильном уровне в иерархии.

+0

Я не использую 'JToken.First', я вызываю' IEnumerable.First() '- то есть он совпадает с первым элементом в цикле' foreach'. В этом случае у меня не было бы причин называть 'Next',' Prev' и т. Д. –

+1

Ответ тот же. 'IEnumerable' будет перечислять дочерние элементы' JToken'. Дети 'JObject' являются объектами' JProperty'. Ребенок 'JProperty' - это его значение. –

Смежные вопросы