In JS or Python you can just iterate over the fields inside the JSON object in runtime and pull out necessary fields. In C# for parsing JSON you need to have a pre-created class with the required fields. It makes parsing much more difficult, when you don't know what fields to meet in the API response. Why can't you create new types on the fly in runtime?
-
2https://stackoverflow.com/a/8972079/477878 – Joachim Isaksson Sep 25 '22 at 06:24
-
6"Why can't you create new types on the fly in runtime?" Well if you could do that, it would no longer be a statically typed language, would it? – Sweeper Sep 25 '22 at 06:28
-
2This is like asking "why are types static in static type languages"... – Matthew Watson Sep 25 '22 at 09:35
-
But note that (if using `Newtonsoft.Json`) you can just do `var item = JsonConvert.DeserializeObject
(jsonString);` and then use `item` to access properies, e.g. `string json = "{number:1000, str:'string', array: [1,2,3,4,5,6]}"; var item = JsonConvert.DeserializeObject – Matthew Watson Sep 25 '22 at 09:49(json); Console.WriteLine(string.Join(", ", item.array));`
1 Answers
It's not hard at all. Parsing is simple and there are compilers, XML parsers, YML parsers, JSON parsers in C, C++ or other statically typed language. It's just impossible to serialize dynamic things like JSON or XML into a static type in those languages
Accessing types that are created dynamically requires emitting code dynamically. How can that be possible in a statically typed language? The compiler has no way to know what fields a struct has and at which offset and how long a field is. Those are new information after parsing the input
A simple way to overcome this is to use reflection which provides type information at runtime. Obviously this incurs a lot of runtime performance wouldn't be possible in performance-sensitive code. One statically typed language that supports reflection is go and json parsing in go also utilizes that feature. Reflection has also been discussed in C++ for a long time but not introduced yet. But there are lots of reflection libraries in C++ that can be used
Why can't you create new types on the fly in runtime?
That means the type system isn't static anymore. Reflection typically requires a runtime platform that's not available in C or C++. How can the compiler knows that a struct has a field named something
and generates access to that field? Only the runtime environment can do that. The .NET framework always has a VM runtime so C#, despite being a statically type language, has always supported reflection. Therefore although it's impossible to serialize dynamic objects into a static type in C#, it's trivial to serialize them in reflected or dynamically generated type
If reflection is not available then there's a simple way to write a parser. Look at the parsers in C++ or C and you'll see that they typically parse data into a tree and walk that tree when accessing the required. Since each graph node always a static type, compiling is simple & possible
For example the below code in C#
dynamic d = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}");
Console.WriteLine(d.number);
Console.WriteLine(d.str);
Console.WriteLine(d.array.Count);
can be done like this in C++
d = json.parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}");
std::cout << d.getChildAsInt("number");
std::cout << d.getChildAsString("str");
std::cout << d.getChildAsArray("array").getChildAsInt("Count");
// or
std::cout << d.getChildAs<int>("number");
std::cout << d.getChildAs<string>("str");
getChildAs*
simply traverses the nodes and return data in the required node

- 37,963
- 15
- 156
- 475