using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using System.Text.Json.Nodes;
[JsonConverter(typeof(WholeConverter))]
public List<Node> allPossibleNodes = new List<Node>();
public List<Node> neighbors = new List<Node>();
class WholeConverter : JsonConverter<Whole>
public List<Node>? allPossibleNodes { get; set; }
public IEnumerable<NeighborItem>? neighborTable { get; set; }
record struct NeighborItem(Node node, List<Node> neighbors);
public override Whole? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
var dto = JsonSerializer.Deserialize<WholeDto>(ref reader, options);
foreach (var item in dto.neighborTable ?? Enumerable.Empty<NeighborItem>().Where(i => i.node != null))
item.node.neighbors = item.neighbors;
if (dto.allPossibleNodes != null)
whole.allPossibleNodes = dto.allPossibleNodes;
public override void Write(Utf8JsonWriter writer, Whole value, JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer,
allPossibleNodes = value.allPossibleNodes,
neighborTable = value.allPossibleNodes.Where(n => n.neighbors.Count > 0).Select(n => new NeighborItem(n, n.neighbors)),
static JsonSerializerOptions options = new () {
IgnoreReadOnlyProperties = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
ReferenceHandler = ReferenceHandler.Preserve,
public static Whole CreateWhole()
for (int i = 0; i < 3; i++) {
w.allPossibleNodes.Add(n);
public static void Test()
var whole = CreateWhole();
var json = JsonSerializer.Serialize(whole, options);
var whole2 = JsonSerializer.Deserialize<Whole>(json, options)!;
var json2 = JsonSerializer.Serialize(whole2, options);
Assert.That(json == json2);
Assert.That(whole.allPossibleNodes.Count == whole2.allPossibleNodes.Count);
Assert.That(whole.allPossibleNodes.Select(n => n.neighbors.Count).SequenceEqual(whole2.allPossibleNodes.Select(n => n.neighbors.Count)));
Assert.That(whole.allPossibleNodes.SelectMany(n => n.neighbors).Select(n => whole.allPossibleNodes.IndexOf(n))
.SequenceEqual(whole2.allPossibleNodes.SelectMany(n => n.neighbors).Select(n => whole2.allPossibleNodes.IndexOf(n))));
public static void Main()
Console.WriteLine("Environment version: {0} ({1}), {2}", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);
Console.WriteLine("System.Text.Json version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");