DotNext by Roman Sakno

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

 ListSegment<T>

Delimits a section of a list.
using System; using System.Collections; using System.Collections.Generic; 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 ListSegment<[System.Runtime.CompilerServices.Nullable(2)] T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyList<T>, IReadOnlyCollection<T> { private readonly int startIndex; private readonly IList<T> list; bool ICollection<T>.IsReadOnly { get { return true; } } public int Count { get; } public T this[int index] { get { return list[ToAbsoluteIndex(index)]; } set { list[ToAbsoluteIndex(index)] = value; } } public ListSegment(IList<T> list, Range range) { (int, int) offsetAndLength = range.GetOffsetAndLength(list.Count); startIndex = offsetAndLength.Item1; Count = offsetAndLength.Item2; this.list = list; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private int ToAbsoluteIndex(int index) { if (!Comparison.Between<int>(index, 0, Count, BoundType.LeftClosed)) throw new ArgumentOutOfRangeException("index"); return index + startIndex; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool ToRelativeIndex(ref int index) { index -= startIndex; return Comparison.Between<int>(index, 0, Count, BoundType.LeftClosed); } public int IndexOf(T item) { int index = list.IndexOf(item); if (!ToRelativeIndex(ref index)) return -1; return index; } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } public bool Contains(T item) { return IndexOf(item) >= 0; } public void CopyTo(T[] array, int arrayIndex) { IList<T> list = this.list; List<T> list2 = list as List<T>; if (list2 == null) { T[] array2 = list as T[]; if (array2 != null) Array.Copy(array2, startIndex, array, arrayIndex, Count); else { for (int i = 0; i < Count; i++) { array[i] = this.list[i + startIndex]; } } } else list2.CopyTo(startIndex, array, arrayIndex, Count); } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } public IEnumerator<T> GetEnumerator() { IEnumerator<T> enumerator = list.GetEnumerator(); Sequence.Skip<T>(enumerator, startIndex); return Sequence.Limit<T>(enumerator, Count, false); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }