I am a C++/CLI programmer and have been trying to implement a very lightweight Json library for my program. I have a nice working code now but the problem is that its about 5 times slower than some of the JSON parsers out there for example Newtonsoft.JSON. So, I tried studying its code to see why it is so fast and came across this statement I cannot wrap my head around. I have researched a lot on google and around here but nothing seems to be able to help me fully understand. Consider the following statement.
JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null);
Here, JsonPosition is a class that has some properties. It only has one constructor that takes JsonContainerType (an enum class) value as an argument. _currentPosition is of the type JsonPosition. _currentState is a variable that holds value of an enum class called State.
To me, it translates to the following.
JsonPosition^ currentPosition = ((_currentState != State::ArrayStart && _currentState != State::ConstructorStart && _currentState != State::ObjectStart) ? something : nullptr);
I cannot make sense of the new JsonPosition?(_currentPosition) part because of (a) the question mark placed between the class name and opening circular bracket, and (b) JsonPosition does not have a constructor that takes an argument of the type JsonPosition.
I found this article that says:
you cannot define a custom default constructor for structs in C#. The compiler automatically provides a default constructor that initializes all fields to their default values.
Taking that as my base, I further did more reliable research and figured out that apparently the C# compiler auto-generates a default constructor for value types (struct is a value type). Therefore allowing JsonPosition to be a nullable type. The code would translate as follows should the C++/CLI compiler would do the same, but since it does not, one must write a default constructor themself.
System::Nullable<JsonPosition^> currentPosition = ((_currentState != State::ArrayStart && _currentState != State::ConstructorStart && _currentState != State::ObjectStart) ? System::Nullable<JsonPosition^>(_currentPosition) : nullptr);
In C++/CLI, the code would be written as follows since in C++/CLI we use the reference handle (^) which unto itself can be null (nullptr) therefore eliminating the need for it to be wrapped in a System::Nullable wrapper.
new JsonPosition?(_currentPosition) would translate directly to just _currentPosition.
JsonPosition^ currentPosition = ((_currentState != State::ArrayStart && _currentState != State::ConstructorStart && _currentState != State::ObjectStart) ? _currentPosition : nullptr);
It is also explicitly stated in Microsoft documentation that in C# 8.0 and later, nullable value types (like JsonPosition?) can represent both a value and null. So, that's something to keep in mind as well.