Given the following polymorphic type hierarchy:
[JsonConverter(typeof(PolymorphicConverter<Base>))]
public record Base
{
private Base() {}
public record A(string Value) : Base;
public record B(int Foobar) : Base;
public record C(Base Recursive) : Base;
}
with the desired serialized json for e.g. A:
{
"type": "A",
"content": {
"value": "jalla"
}
}
Is it possible to create an implementation for PolymorphicConverter that's not tied to the type Base, is performant and is thread safe?
This is an implementation that works and is performant, but not thread safe:
using System;
using Newtonsoft.Json;
Base a = new Base.A("foobar");
var json = JsonConvert.SerializeObject(a);
Console.WriteLine(json);
[JsonConverter(typeof(PolymorphicConverter<Base>))]
public record Base
{
private Base() {}
public record A(string Value) : Base;
public record B(int Foobar) : Base;
public record C(Base Recursive) : Base;
}
public class PolymorphicConverter<TBase> : JsonConverter where TBase : class
{
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
var type = value?.GetType() ?? throw new NotImplementedException();
var converter = serializer.ContractResolver.ResolveContract(type).Converter;
serializer.ContractResolver.ResolveContract(type).Converter = null;
writer.WriteStartObject();
writer.WritePropertyName("type");
writer.WriteValue(type.Name);
writer.WritePropertyName("content");
serializer.Serialize(writer, value);
serializer.ContractResolver.ResolveContract(type).Converter = converter;
writer.WriteEndObject();
}
public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanConvert(Type objectType)
{
return typeof(TBase).IsAssignableFrom(objectType);
}
}
ReadJson()so I didn't discuss it in my answer. If you need help with that also, can you let us know where you are stuck (or ask a second question)?