using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
public interface Dto<T> : Dto where T : Entity;
[JsonDerivedType(derivedType: typeof(CourseDto))]
[JsonDerivedType(derivedType: typeof(DeletedDto))]
[JsonPolymorphic(UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)]
public sealed record CourseEntity(Guid id, string Name) : Entity;
public sealed record DeletedDto(string Id) : Dto;
public sealed record CourseDto(
public sealed record SynchronizableWrapper<T>(T[]? Added, T[]? Updated, DeletedDto[]? Deleted)
: SynchronizableWrapper(Added, Updated, Deleted) where T : class, Dto
public new T[]? Added => (T[]?) base.Added;
public new T[]? Updated => (T[]?) base.Updated;
public new DeletedDto[]? Deleted => base.Deleted;
public record SynchronizableWrapper(Dto[]? Added, Dto[]? Updated, DeletedDto[]? Deleted)
public Dto[]? Added { get; set; } = Added;
public Dto[]? Updated { get; set; } = Updated;
public DeletedDto[]? Deleted { get; set; } = Deleted;
public static async Task Test()
var wrapper = await AsyncGetChangedEntities<CourseDto, CourseEntity>();
var json2 = JsonSerializer.Serialize(wrapper, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine("Re-serialized {0}:", wrapper);
Console.WriteLine(json2);
public static async Task<SynchronizableWrapper?> AsyncGetChangedEntities<T, T2>() where T : class, Dto<T2> where T2 : class, Entity
var stream = new MemoryStream(
"id": "6a38a67c-46e3-497e-ab5f-3fa6b8d15cc4",
"name": "SomeCourse's name"
"id": "6a38a67c-46e3-497e-ab5f-3fa6b8d15cc4"
var _serializerOptions = new JsonSerializerOptions
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
return await JsonSerializer.DeserializeAsync<SynchronizableWrapper<T>>(stream, _serializerOptions);
public static async Task Main(string[] args)
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: ");