Description
from @blankensteiner:
As explained in the related issue #32429, I'm currently writing my own (de)serializer because I need to support creating the object without calling a constructor (using System.Runtime.Serialization.FormatterServices.GetUninitializedObject) and getting/setting private and read-only fields (using System.Reflection.FieldInfo.SetValue).
Just like JsonSerializer and JsonDocument, I am building on top of Utf8JsonReader and Utf8JsonWriter.
That decision was made because it's encouraged:
The Utf8JsonReader is a low-level type that can be used to build custom parsers and deserializers
and because I want to generate the exact same JSON and if possible also respect all options (JsonWriterOptions, JsonReaderOptions, JsonSerializerOptions).
However, I find that I'm not able to just focus on mapping from C# fields to JSON properties (and vise versa), because I have to duplicate functionality/behavior. I think these methods are missing from the current API:
public ref partial struct Utf8JsonReader
{
public TimeSpan GetTimeSpan();
public bool TryGetTimeSpan(out TimeSpan value);
}
public sealed partial class Utf8JsonWriter : System.IAsyncDisposable, System.IDisposable
{
public void WriteString(string propertyName, TimeSpan value)
}
public readonly partial struct JsonElement
{
public TimeSpan GetTimeSpan();
public bool TryGetTimeSpan(out TimeSpan value);
}
In my opinion, it's the domain of Utf8JsonReader and Utf8JsonWriter to know how to (de)serialize the primitive types to whatever data types JSON happens to support. They already know how to do this for most types, but inconsistently TimeSpan is left out. By that logic (the arguments for not adding it), I don't see why DateTime and DateTimeOffset are handled in the reader and writer, but not TimeSpan? The challenge is the same: We have a C#-type and a JSON string, do some magic.
In .NET Core 3.1 a TimeSpan is mapped to an object, but in .NET 5 that will change as TimeSpans are mapped to strings. That is an implementation I have to duplicate in my serializer. If that logic was instead pushed down into Utf8JsonReader and Utf8JsonWriter, all users (and people like me creating serializers) could be free'ed from dealing with that lower-level logic.
We should just pass through the wish to get a TimeSpan and not care what JSON data type the authors of Utf8JsonReader/Writer chose for it and what mapping logic there currently is.