Json.NET C #: JToken.Parent всегда равен нулю - PullRequest
0 голосов
/ 24 августа 2018

Я работаю над системой сериализации Json.NET, которая в значительной степени зависит от пользовательских преобразователей, обработчика контрактов и атрибутов. Система направлена ​​на обработку десериализации ссылок, включая взаимные ссылки и разрешение, которые не чувствительны к порядку. Я не использую для этого нативную систему Json.NET, потому что у нас особые требования.

Моя текущая система идентифицирует запрос на ссылку, когда объект десериализуется. Эта ссылка принимает форму числового идентификатора или удобочитаемой строки. Если запрашиваемый объект ссылки уже был десериализован, тогда нуждающемуся в ссылке объекту просто присваивается правильное значение из большого словаря. Если это не так, отправляется «запрос ссылки». Этот запрос содержит объект и идентификатор.

Когда я писал эту систему, я не осознавал, что изменение объекта в запросе ссылки не приведет к автоматическому изменению его получателя. Таким образом, это просто не работает.

Однако решить это должно быть довольно просто. Если я получаю инкапсулирующий владелец поля объекта (если, например, Wine определен в Dinner, мне нужно получить Dinner при проверке Wine во время десериализации), я могу просто использовать отражение для установки поля. По сути, я храню адрес поля. И из того, что я понял, это должно быть совершенно возможно путем обхода иерархии Json через JToken.Parent. Однако, когда я пытаюсь получить доступ к этому полю в объекте, у которого должен быть родитель, это значение равно нулю. Я искал и искал, но я не нашел признаков того, что Parent - это то, что мне нужно установить самостоятельно; Я предположил, что это было обработано внутри Json.NET. Почему это ноль?

Ниже приведен пример. FoodExample содержит поле Food, которое само определяет поле Wine.

public class FoodExample
{
    // This meal contains a defined instance of Wine, instead of a reference.
    public Food definedMeal = null;

    public FoodExample()
    {

    }

    public void Initialise()
    {
        Food definedMeal = new Food("Steak", new Wine("Pinot Noir", 15.99f));
    } 
}

При десериализации Wine с использованием моего пользовательского конвертера я запрашиваю поле Wine JToken.Parent, например:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    Debug.Log("Deserialising definition: " + objectType);

    // Create a JObject. Use it to get a JReader, 
    JObject jObject = JObject.Load(reader);
    JsonReader jsonReader = jObject.CreateReader();

    Debug.Log("Parent: " + (jObject.Parent == null)); // Prints true
}

Выход Json:

{
  "definedMeal": {
    "ID": 1,
    "name": "Steak",
    "pairsWellWith": {
      "ID": 0,
      "price": 15.99,
      "name": "Pinot Noir"
    }
  }
}

Родитель для обоих объектов в этой иерархии отображается как нулевой при прохождении через мой пользовательский конвертер.

Вероятно, стоит упомянуть, что я работаю в Unity3D.

1 Ответ

0 голосов
/ 07 сентября 2018

Цитирование этот ответ:

Невозможно получить доступ к родителю, потому что родительские объекты всегда создаются после своих потомков.То есть вам нужно прочитать json, из которого состоит объект, до конца, чтобы иметь возможность полностью построить объект, и к тому времени, как вы прочитали последнюю скобку объекта, вы уже прочитали все его дочерние элементы.Когда ребенок проанализировал, у него еще нет родителя, чтобы получить ссылку.

...