DotNext by .NET Foundation and Contributors

<PackageReference Include="DotNext" Version="5.13.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)] [NullableContext(1)] [Nullable(0)] public readonly struct ReadOnlyCollectionView<[Nullable(2)] TInput, [Nullable(2)] TOutput> : IReadOnlyCollection<TOutput>, IEnumerable<TOutput>, IEnumerable, IEquatable<ReadOnlyCollectionView<TInput, TOutput>> { private readonly IReadOnlyCollection<TInput> source; private readonly Func<TInput, TOutput> mapper; public int Count { get { IReadOnlyCollection<TInput> readOnlyCollection = source; if (readOnlyCollection == null) return 0; return readOnlyCollection.Count; } } public ReadOnlyCollectionView(IReadOnlyCollection<TInput> collection, Func<TInput, TOutput> mapper) { if (collection == null) throw new ArgumentNullException("collection"); source = collection; if (mapper == null) throw new ArgumentNullException("mapper"); this.mapper = mapper; } public ReadOnlyCollectionView(IReadOnlyCollection<TInput> collection, Converter<TInput, TOutput> mapper) { this = new ReadOnlyCollectionView<TInput, TOutput>(collection, Unsafe.As<Func<TInput, TOutput>>((object)mapper)); } public IEnumerator<TOutput> GetEnumerator() { IReadOnlyCollection<TInput> readOnlyCollection = source; bool flag = (readOnlyCollection == null || readOnlyCollection.Count == 0) ? true : false; if (!flag && mapper != null) return Enumerable.Select<TInput, TOutput>((IEnumerable<TInput>)source, mapper).GetEnumerator(); return Enumerable.Empty<TOutput>().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private bool Equals([In] [IsReadOnly] ref ReadOnlyCollectionView<TInput, TOutput> other) { if (source == other.source) return mapper == other.mapper; return false; } public bool Equals([Nullable(new byte[] { 0, 1, 1 })] ReadOnlyCollectionView<TInput, TOutput> other) { return Equals(ref other); } public override int GetHashCode() { return RuntimeHelpers.GetHashCode(source) ^ mapper.GetHashCode(); } [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(ref other2); } public static bool operator ==([In] [IsReadOnly] [Nullable(new byte[] { 0, 1, 1 })] ref ReadOnlyCollectionView<TInput, TOutput> first, [In] [IsReadOnly] [Nullable(new byte[] { 0, 1, 1 })] ref ReadOnlyCollectionView<TInput, TOutput> second) { return first.Equals(ref second); } public static bool operator !=([In] [IsReadOnly] [Nullable(new byte[] { 0, 1, 1 })] ref ReadOnlyCollectionView<TInput, TOutput> first, [In] [IsReadOnly] [Nullable(new byte[] { 0, 1, 1 })] ref ReadOnlyCollectionView<TInput, TOutput> second) { return !first.Equals(ref second); } } }