From 2813ef44942022911261601f458a8e2f044d220e Mon Sep 17 00:00:00 2001 From: Alexander Radchenko Date: Sat, 10 Dec 2016 02:33:44 +0700 Subject: [PATCH] Make it easier to iterate through an ArraySegment (#8559) * Make it easier to iterate through an ArraySegment. See Make it easier to iterate through an ArraySegment --- src/mscorlib/model.xml | 8 +++ src/mscorlib/src/System/ArraySegment.cs | 71 +++++++++++-------------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/mscorlib/model.xml b/src/mscorlib/model.xml index 33c6525e9a10..441df0d8bd70 100644 --- a/src/mscorlib/model.xml +++ b/src/mscorlib/model.xml @@ -341,6 +341,7 @@ + @@ -348,6 +349,13 @@ + + + + + + + diff --git a/src/mscorlib/src/System/ArraySegment.cs b/src/mscorlib/src/System/ArraySegment.cs index 1e76d174ced0..676452abae81 100644 --- a/src/mscorlib/src/System/ArraySegment.cs +++ b/src/mscorlib/src/System/ArraySegment.cs @@ -28,10 +28,10 @@ namespace System [Serializable] public struct ArraySegment : IList, IReadOnlyList { - private T[] _array; - private int _offset; - private int _count; - + private readonly T[] _array; + private readonly int _offset; + private readonly int _count; + public ArraySegment(T[] array) { if (array == null) @@ -67,7 +67,7 @@ public T[] Array Contract.Assert( (null == _array && 0 == _offset && 0 == _count) || (null != _array && _offset >= 0 && _count >= 0 && _offset + _count <= _array.Length), "ArraySegment is invalid"); - + return _array; } } @@ -109,7 +109,16 @@ public int Count return _count; } } - + + public Enumerator GetEnumerator() + { + if (_array == null) + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray); + Contract.EndContractBlock(); + + return new Enumerator(this); + } + public override int GetHashCode() { if (_array == null) @@ -184,7 +193,7 @@ int IList.IndexOf(T item) int index = System.Array.IndexOf(_array, item, _offset, _count); - Contract.Assert(index == -1 || + Contract.Assert(index == -1 || (index >= _offset && index < _offset + _count)); return index >= 0 ? index - _offset : -1; @@ -269,46 +278,34 @@ bool ICollection.Remove(T item) #endregion #region IEnumerable - IEnumerator IEnumerable.GetEnumerator() - { - if (_array == null) - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray); - Contract.EndContractBlock(); - return new ArraySegmentEnumerator(this); - } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #endregion #region IEnumerable - IEnumerator IEnumerable.GetEnumerator() - { - if (_array == null) - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray); - Contract.EndContractBlock(); - return new ArraySegmentEnumerator(this); - } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); #endregion [Serializable] - private sealed class ArraySegmentEnumerator : IEnumerator + public struct Enumerator : IEnumerator { - private T[] _array; - private int _start; - private int _end; + private readonly T[] _array; + private readonly int _start; + private readonly int _end; // cache Offset + Count, since it's a little slow private int _current; - internal ArraySegmentEnumerator(ArraySegment arraySegment) + internal Enumerator(ArraySegment arraySegment) { Contract.Requires(arraySegment.Array != null); Contract.Requires(arraySegment.Offset >= 0); Contract.Requires(arraySegment.Count >= 0); Contract.Requires(arraySegment.Offset + arraySegment.Count <= arraySegment.Array.Length); - _array = arraySegment._array; - _start = arraySegment._offset; - _end = _start + arraySegment._count; - _current = _start - 1; + _array = arraySegment.Array; + _start = arraySegment.Offset; + _end = arraySegment.Offset + arraySegment.Count; + _current = arraySegment.Offset - 1; } public bool MoveNext() @@ -325,19 +322,15 @@ public T Current { get { - if (_current < _start) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted(); - if (_current >= _end) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded(); + if (_current < _start) + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted(); + if (_current >= _end) + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded(); return _array[_current]; } } - object IEnumerator.Current - { - get - { - return Current; - } - } + object IEnumerator.Current => Current; void IEnumerator.Reset() {