DotNext by Roman Sakno

<PackageReference Include="DotNext" Version="2.7.0" />

 ReadOnlyCollectionView<TInput, TOutput>

public struct ReadOnlyCollectionView<TInput, TOutput> : IReadOnlyCollection<TOutput>, IEnumerable<TOutput>, IEnumerable, IEquatable<ReadOnlyCollectionView<TInput, TOutput>>
Represents lazily converted read-only collection.
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace DotNext.Collections.Generic { [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public readonly struct ReadOnlyCollectionView<[System.Runtime.CompilerServices.Nullable(2)] TInput, [System.Runtime.CompilerServices.Nullable(2)] TOutput> : IReadOnlyCollection<TOutput>, IEnumerable<TOutput>, IEnumerable, IEquatable<ReadOnlyCollectionView<TInput, TOutput>> { private readonly IReadOnlyCollection<TInput> source; [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] private readonly ValueFunc<TInput, TOutput> mapper; public int Count => source.Count; public ReadOnlyCollectionView(IReadOnlyCollection<TInput> collection, [In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] ref ValueFunc<TInput, TOutput> mapper) { if (collection == null) throw new ArgumentNullException("collection"); source = collection; this.mapper = mapper; } public IEnumerator<TOutput> GetEnumerator() { return Enumerable.Select<TInput, TOutput>((IEnumerable<TInput>)source, mapper.ToDelegate()).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public bool Equals([System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] ReadOnlyCollectionView<TInput, TOutput> other) { if (source == other.source) return ref mapper == ref other.mapper; return false; } public override int GetHashCode() { return RuntimeHelpers.GetHashCode(source) ^ mapper.GetHashCode(); } [System.Runtime.CompilerServices.NullableContext(2)] public override bool Equals(object other) { if (!(other is ReadOnlyCollectionView<TInput, TOutput>)) return object.Equals(source, other); ReadOnlyCollectionView<TInput, TOutput> other2 = (ReadOnlyCollectionView<TInput, TOutput>)other; return Equals(other2); } public static bool operator ==([System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] ReadOnlyCollectionView<TInput, TOutput> first, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] ReadOnlyCollectionView<TInput, TOutput> second) { return first.Equals(second); } public static bool operator !=([System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] ReadOnlyCollectionView<TInput, TOutput> first, [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] ReadOnlyCollectionView<TInput, TOutput> second) { return !first.Equals(second); } } }