Skip to content

Instantly share code, notes, and snippets.

@SQL-MisterMagoo
Created August 1, 2023 23:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SQL-MisterMagoo/0be37110225b977f0aa2023b39aa8b8d to your computer and use it in GitHub Desktop.
Save SQL-MisterMagoo/0be37110225b977f0aa2023b39aa8b8d to your computer and use it in GitHub Desktop.
Why dotnet, why? Or how to deserialize with a collection of interface
using System.Text.Json;
using System.Text.Json.Serialization;
/* Setup */
Thing[] someThings = { new("1"), new("2") };
var myThings = new Things(someThings);
/* Staying in dotnet - this all works as expected */
var asInterfaces = myThings as IThings;
var asThings = asInterfaces as Things;
var castInterfaces2 = (IThings)asThings;
var castThings2 = (Things)asInterfaces;
Console.WriteLine("dotnet world: "+JsonSerializer.Serialize(castThings2));
/* Round trip JSON De-Serialization fails without the converter
* but doesn't say exactly why */
var json = JsonSerializer.Serialize(myThings);
Things? newThings = JsonSerializer.Deserialize<Things>(
json,
new JsonSerializerOptions(JsonSerializerDefaults.General)
{
Converters = { new CollectionConverter<Thing, IThing>() }
}
);
/* serialize just to display */
var json2 = JsonSerializer.Serialize(newThings);
Console.WriteLine("JSON world: "+json2);
Console.ReadLine();
/* Interfaces */
interface IThing{ string Id { get; } }
interface IThings{ IEnumerable<IThing> AllThings { get; } }
/* Implementation */
class Thing(string id) : IThing { public string Id { get; } = id; }
class Things(IEnumerable<IThing> allThings) : IThings
{
public IEnumerable<IThing> AllThings { get; } = allThings;
}
/* JsonConverter */
public class CollectionConverter<T, U> : JsonConverter<IEnumerable<U>> where T : U
{
public override IEnumerable<U>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> JsonSerializer.Deserialize<IEnumerable<T>>(ref reader, options)?.Cast<U>();
public override void Write(Utf8JsonWriter writer, IEnumerable<U> value, JsonSerializerOptions options)
=> JsonSerializer.Serialize(writer, value.Cast<T>(), options);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment