create a json serializer for a tagged union in csharp

To create a JSON serializer for a tagged union in C#, you can use the Newtonsoft.Json library which provides a powerful serializer and deserializer for JSON data.

First, define your tagged union class with a discriminated union type:

main.cs
public class TaggedUnion<T>
{
    [JsonProperty(PropertyName = "type")]
    public string Discriminator { get; set; }

    [JsonProperty(PropertyName = "value")]
    public T Value { get; set; }
}
197 chars
9 lines

This class has two properties: one property of type string called Discriminator which is used as a discriminated union tag and another property of generic type T called Value which holds the actual value of the union.

Next, define your union types:

main.cs
public class TypeA
{
    public string PropertyA { get; set; }
}

public class TypeB
{
    public int PropertyB { get; set; }
}
128 chars
10 lines

Now, you can create a JSON serializer that can serialize and deserialize your tagged union:

main.cs
public class TaggedUnionJsonSerializer<T>
{
    private readonly JsonSerializer _jsonSerializer;

    public TaggedUnionJsonSerializer()
    {
        _jsonSerializer = new JsonSerializer();
        _jsonSerializer.TypeNameHandling = TypeNameHandling.Auto;
    }

    public string Serialize(TaggedUnion<T> data)
    {
        StringWriter stringWriter = new StringWriter();
        using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter))
        {
            _jsonSerializer.Serialize(jsonTextWriter, data);
        }

        return stringWriter.ToString();
    }

    public TaggedUnion<T> Deserialize(string json)
    {
        StringReader stringReader = new StringReader(json);
        using (JsonTextReader jsonTextReader = new JsonTextReader(stringReader))
        {
            return _jsonSerializer.Deserialize<TaggedUnion<T>>(jsonTextReader);
        }
    }
}
891 chars
31 lines

This serializer uses the TypeNameHandling.Auto option to include type information in the JSON string so that the deserializer knows which union type to create when deserializing the JSON string.

gistlibby LogSnag