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.Threading.Tasks;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using System.Text.Json.Nodes;
public record Measurement(string Timestamp, decimal Value);
public record Header<TCollection> (string Id, TCollection Measurements) where TCollection : IEnumerable<Measurement>;
public class TotalMeasurementCollection : AggregatingCollection<Measurement>
public int TotalAdded { get; set; }
public decimal TotalValue { set; get; }
public override void Add(Measurement item) => (this.TotalAdded, this.TotalValue) = (this.TotalAdded + 1, this.TotalValue + item.Value);
public class AggregatingCollection<TItem> : ICollection<TItem>
public virtual void Add(TItem item) {}
public bool Contains(TItem item) => false;
public void CopyTo(TItem[] array, int arrayIndex) => ArgumentNullException.ThrowIfNull(array);
public bool IsReadOnly => false;
public bool Remove(TItem item) => false;
public IEnumerator<TItem> GetEnumerator() => Enumerable.Empty<TItem>().GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
public static async Task Test()
var values = Enumerable.Range(0, 3077).Select(v => (decimal)v/5M);
var expectedAverage = values.Average();
await using (var stream = await GetJsonStream(values))
var result = await JsonSerializer.DeserializeAsync<Header<TotalMeasurementCollection>>(stream);
var average = result!.Measurements!.TotalValue / result!.Measurements!.TotalAdded;
Console.WriteLine("\nAverage measurement: {0}", average);
Assert.AreEqual(expectedAverage, average);
static Task<Stream> GetJsonStream(IEnumerable<decimal> values)
Stream stream = new MemoryStream();
JsonSerializer.Serialize(stream, new Header<IEnumerable<Measurement>>("hello", values.Select(v => new Measurement(DateTime.Now.ToString(), v))));
return Task.FromResult(stream);
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: ");