using System.Collections.Generic;
using System.Text.Json.Serialization;
[System.Text.Json.Serialization.JsonConverter(typeof(ItemCollectionJsonConverter))]
public partial class ItemCollection<T> : ICollection<T> {
internal ItemCollection(List<T> items) {
Items = items ?? throw new ArgumentNullException();
public ItemCollection() {
public List<T> Items { get; set; }
public class ItemCollectionJsonConverter : JsonConverterFactory
public override bool CanConvert(Type typeToConvert) => GetItemCollectionValueType(typeToConvert) != null;
public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options)
=> (JsonConverter)Activator.CreateInstance(typeof(ItemCollectionJsonConverterInner<>).MakeGenericType(GetItemCollectionValueType(type)!))!;
static Type? GetItemCollectionValueType(Type type) =>
(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ItemCollection<>)) ? type.GetGenericArguments()[0] : null;
class ItemCollectionJsonConverterInner<T> : JsonConverter<ItemCollection<T>>
public List<T>? Items { get; set; }
public override ItemCollection<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
new ItemCollection<T>((JsonSerializer.Deserialize<ItemCollectionDTO>(ref reader, options)?.Items) ?? throw new JsonException());
public override void Write(Utf8JsonWriter writer, ItemCollection<T> value, JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, new ItemCollectionDTO { Items = value.Items }, options);
public partial class ItemCollection<T>
#region ICollection<T> Members
public void Add(T item) => Items.Add(item);
public void Clear() => Items.Clear();
public bool Contains(T item) => Items.Contains(item);
public void CopyTo(T[] array, int arrayIndex) => Items.CopyTo(array, arrayIndex);
public int Count => Items.Count;
public bool IsReadOnly => ((IList<T>)Items).IsReadOnly;
public bool Remove(T item) => Items.Remove(item);
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator() => Items.GetEnumerator();
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
public static void Test()
var collection = new ItemCollection<string>
var options = new JsonSerializerOptions
var json = JsonSerializer.Serialize(collection, options);
var collection2 = JsonSerializer.Deserialize<ItemCollection<string>>(json, options);
Assert.IsTrue(collection.SequenceEqual(collection2!));
public static void Main()
Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version);
Console.WriteLine("System.Text.Json version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");