2

So I've been looking to convert my Json array into an array of objects in Unity. I've found my solution from a 2 yeard old thread without explanation but I'm curious as to how it actually works.
If I use Visual Studio to look for the definition of FromJson it shows me this
public static T FromJson<T>(string json);
As I understand is that FromJson asks for an object to be filled, I give the class MyWrapper but besides telling MyWrapper that he contains a list of Question I never ask it to create a new item in the list. So how does it actually fill the list?

C#

MyWrapper wrappedQuestions = JsonUtility.FromJson<MyWrapper>(jsonString);

[Serializable]
public class MyWrapper
{
    public List<Question> questions;
}

[Serializable]
public class Question
{
    public int questionType;
    public string questionString;
    public int questionAnswer;
}

Json

{
    "questions": [
      {
        "questionType":  1,
        "questionString": "4^2",
        "questionAnswer": 16
      },
      {
        "questionType":  2,
        "questionString": "√(25)",
        "questionAnswer": 5
      }
    ]
}

I'm still a beginner programmer so I hope I'am able to ask such questions here.

Simon
  • 385
  • 4
  • 19
  • [Maybe read the docs?](https://docs.unity3d.com/ScriptReference/JsonUtility.FromJson.html). *So how does it actually fill the list?* It's a parser, that's what parsers do? Your question is not clear – Liam Dec 05 '17 at 11:57

2 Answers2

3

If you wonder why you need a wrapper for that, that's simply because Unity engineers did not add direct support for primitive types or arrays. It's just how they programmed it. Most Json API are not like this.

So how does it actually fill the list?

Reflection.

1.It reads the json you passed to it. It detects the questions variable in the json. It detects that the questions variable is an array due to the format such as [] and the commas that separates each item.

2.It finds the type of that questions variable which is Question or List of Question.

3.It uses Activator.CreateInstance to create new instance of Question, read each value from each variable in the json and then fill them up with reflection with that new instance it created.

4. It returns the new instance that is filled.

If you read and understand how to do basic stuff with reflection in C#, you may be able to make your own simple Json parser with the Queue class.

Finally, you can use the JsonHelper wrapper from this answer to serialize/de-serialize arrays easily without having to make a wrapper for each class.

Programmer
  • 121,791
  • 22
  • 236
  • 328
1

As JSON stands for Javascript Object Notation, JSON objects (strings) follow a pattern. For any string to parsed and converted to the object, it has to be a valid JSON. It has certain rules/syntax,

for example

[ ] is for array/list,

{ } is for objects

and every object can contain key-value pairs (separated by colon :) to represent variables along with their values

{ "Key" : "Value" }

Now JSON parser is aware of these rules so it can check if any string is valid JSON.

What does it need to know to convert a JSON into a class object?

The class type you provide here :

JsonUtility.FromJson<MyWrapper>(jsonString);

is MyWrapper.

It should have the same structure as your jsonString.

Let's break down your jsonString to map it with the class structure:

This represents a MyWrapper object. which contains only one property called questions, which is an empty list.

{                  
    "questions": [ ]
}

if questions have any element in it, it would be of type Question we can write it as following in JSON:

{
    "questionType":  1,  // int value
    "questionString": "4^2", // string value
    "questionAnswer": 16 // int value
}

now if questions have more than one elements they would be separated by a comma:

"questions": [
  {
    "questionType":  1,
    "questionString": "4^2",
    "questionAnswer": 16
  },
  {
    "questionType":  2,
    "questionString": "√(25)",
    "questionAnswer": 4
  },
  ...
]

JSON parser is aware of all these rules so by looking at class structure it can parse the string and create an object of the stated class provided that JSON is valid and class structure matches with JSON structure.

That's all I could say about this, hope you got the basic understanding.

Umair M
  • 10,298
  • 6
  • 42
  • 74