DotNext by .NET Foundation and Contributors

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

 Enumerator

public static class Enumerator
Various methods to work with classes implementing IEnumerable<T> interface.
using System; using System.Buffers; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; namespace DotNext.Collections.Generic { [NullableContext(1)] [Nullable(0)] public static class Enumerator { [StructLayout(LayoutKind.Auto)] [NullableContext(0)] public struct LimitedEnumerator<[Nullable(2)] T> : IEnumerator<T>, IEnumerator, IDisposable { private readonly IEnumerator<T> enumerator; private readonly bool disposeEnumerator; private int count; [Nullable(1)] public T Current { [IsReadOnly] [NullableContext(1)] get { return enumerator.Current; } } [Nullable(2)] object IEnumerator.Current { [IsReadOnly] get { return Current; } } internal LimitedEnumerator(IEnumerator<T> enumerator, int limit, bool leaveOpen) { this.enumerator = enumerator; disposeEnumerator = !leaveOpen; count = limit; } public bool MoveNext() { if (count-- > 0) return enumerator.MoveNext(); return false; } [IsReadOnly] public void Reset() { enumerator?.Reset(); } public void Dispose() { if (disposeEnumerator) enumerator?.Dispose(); this = default(LimitedEnumerator<T>); } } public static bool Skip<[Nullable(2)] T>(this IEnumerator<T> enumerator, int count) { while (count > 0) { if (!enumerator.MoveNext()) return false; count--; } return true; } [NullableContext(0)] public static bool Skip<TEnumerator, [Nullable(2)] T>(ref TEnumerator enumerator, int count) where TEnumerator : struct, IEnumerator<T> { while (count > 0) { if (!enumerator.MoveNext()) return false; count--; } return true; } [return: Nullable(new byte[] { 0, 1 })] public static LimitedEnumerator<T> Limit<[Nullable(2)] T>(this IEnumerator<T> enumerator, int count, bool leaveOpen = false) { return new LimitedEnumerator<T>(enumerator, count, leaveOpen); } public static IEnumerator<T> ToEnumerator<[Nullable(2)] T>([Nullable(new byte[] { 0, 1 })] ReadOnlyMemory<T> memory) { if (!memory.IsEmpty) { if (!MemoryMarshal.TryGetArray(memory, out ArraySegment<T> segment)) return <ToEnumerator>g__ToEnumeratorSlow|3_0(memory); return segment.GetEnumerator(); } return Enumerable.Empty<T>().GetEnumerator(); } public static IEnumerator<T> ToEnumerator<[Nullable(2)] T>([In] [IsReadOnly] [Nullable(new byte[] { 0, 1 })] ref ReadOnlySequence<T> sequence) { if (!sequence.IsEmpty) { if (!sequence.IsSingleSegment) return <ToEnumerator>g__ToEnumeratorSlow|4_0(sequence.GetEnumerator()); return ToEnumerator(sequence.First); } return Enumerable.Empty<T>().GetEnumerator(); } public static IAsyncEnumerator<T> GetAsyncEnumerator<[Nullable(2)] T>(this IEnumerable<T> enumerable, CancellationToken token = default(CancellationToken)) { if (enumerable == null) throw new ArgumentNullException("enumerable"); return new AsyncEnumerable.Proxy<T>.Enumerator(enumerable, token); } } }