using System.Collections.Generic;
public record PrintCustomer
public string AccountNumber { get; init; }
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.Objects)]
public List<Property> Properties { get; init; } = new List<Property>();
public abstract class Property
public Guid Id { get; set; }
public abstract object GetValue();
public abstract Type GetDataType();
public static Property CreateNew<T>(Guid id, T value) => new Property<T> { Id = id, Value = value };
public override string ToString() => $"{Id} = {GetValue()} <{GetDataType()}>";
public class Property<T> : Property
public T Value { get; set; }
public override object GetValue() => Value;
public override Type GetDataType() => typeof(T);
static void Main(string[] args)
var customer = new PrintCustomer()
AccountNumber = "Foo#123",
Properties = new List<Property>()
new Property<int> { Id = Guid.NewGuid(), Value = 123 },
new Property<string> { Id = Guid.NewGuid(), Value = "Foo" },
new Property<decimal> { Id = Guid.NewGuid(), Value = 99.99m },
new Property<DateTime> { Id = Guid.NewGuid(), Value = DateTime.UtcNow },
Property.CreateNew(Guid.NewGuid(), 123),
Property.CreateNew(Guid.NewGuid(), 456L),
Property.CreateNew(Guid.NewGuid(), "Bar"),
Property.CreateNew(Guid.NewGuid(), 4812.4839m),
Property.CreateNew(Guid.NewGuid(), DateTimeOffset.UtcNow),
Console.Out.WriteLine("Expected:\n");
foreach (var prop in customer.Properties)
Console.Out.WriteLine($"Property {prop}");
Console.Out.WriteLine("");
Console.Out.WriteLine("Serialized:\n");
var json = JsonConvert.SerializeObject(customer, Formatting.Indented);
Console.Out.WriteLine($"JSON = {json}\n");
Console.Out.WriteLine("");
Console.Out.WriteLine("Deserialized:\n");
var deserializedCustomer = JsonConvert.DeserializeObject<PrintCustomer>(json);
foreach (var prop in deserializedCustomer.Properties)
Console.Out.WriteLine($"Property {prop}");