Suppose I have a class with a ToString
function. I can easily customize json.net serialization so that the class is written as the string returned by ToString
. That is easy.
But I do not like the idea of creating a very short lived string just for that purpose. When serializing a lot of objects (in the hundred of thousands) this creates extra pressure on the GC.
Instead, I would like to write to the JsonWriter
directly mimicking the logic of the ToString
function, i.e. to have something like this:
class X
{
public override string ToString(){ ... }
public void Write(JsonWriter writer){ ... }
}
The json serializer will be customized to invoke X.Write
function, but the problem is that I do not know how to implement it properly so that it respects the configured formatting and all the other json settings.
My current implementation has to resort to reflection:
private static readonly Action<JsonWriter, JsonToken> s_internalWriteValue = (Action<JsonWriter, JsonToken>)Delegate
.CreateDelegate(typeof(Action<JsonWriter, JsonToken>), typeof(JsonWriter)
.GetMethod("InternalWriteValue", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic));
...
internal void Write(JsonWriter writer)
{
...
s_internalWriteValue(writer, JsonToken.String);
writer.WriteRaw("\"[");
writer.WriteRaw(statusCode);
writer.WriteRaw(",");
writer.WriteRaw(isCompilerGeneratedCode);
writer.WriteRaw(",");
writer.WriteRaw(scope);
writer.WriteRaw(",");
writer.WriteRaw(kind);
writer.WriteRaw(",");
writer.WriteRaw(rawName);
writer.WriteRaw("] ");
writer.WriteRaw(Signature);
writer.WriteRaw("\"");
}
I failed to find a solution that would use only public API. I use json.net 13.0.3
So my question is - how can we have this approach using only public json.net API?
rawName
,Signature
and so on include any characters that must be escaped. See e.g. this answer to How to use string interpolation and verbatim string together to create a JSON string literal? for a breakdown of what you need to do to correctly format JSON strings manually.