Skip to content

Instantly share code, notes, and snippets.

@shirshov
Created May 19, 2021 19:43
Show Gist options
  • Save shirshov/4a3a5e1e9e1acc93a1d5d91972ef49c1 to your computer and use it in GitHub Desktop.
Save shirshov/4a3a5e1e9e1acc93a1d5d91972ef49c1 to your computer and use it in GitHub Desktop.
Serialization of "Discriminated Unions" made of C# 9's records
using System;
using Newtonsoft.Json;

var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects };

var serialized = JsonConvert.SerializeObject(new NetworkAsset[] {
    new User("alexsh"),
    new Printer("192.168.1.2", "HP LaserJet")
}, settings: settings);

var deserialized = JsonConvert.DeserializeObject<NetworkAsset[]>(serialized, settings: settings);

Console.WriteLine(serialized);
/*
OUTPUT:

[{"$type":"User, DU","Name":"alexsh"},{"$type":"Printer, DU","IPAddress":"192.168.1.2","Model":"HP LaserJet"}]

*/

foreach (var a in deserialized)
    Console.WriteLine(Format(a));
/*
OUTPUT:

User: alexsh
Printer: HP LaserJet (192.168.1.2)

*/

// This function takes the DU's type
static string Format(NetworkAsset a) => a switch {
    User u => $"User: {u.Name}",
    Printer p => $"Printer: {p.Model} ({p.IPAddress})"
    // Alas, no way to do exhaustive check
};

// The "DU" and its members
interface NetworkAsset { }
record User(string Name) : NetworkAsset;
record Printer(string IPAddress, string Model) : NetworkAsset;
@shirshov
Copy link
Author

dotnet new --console, then replace entire content of Program.cs with the above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment