diff options
Diffstat (limited to 'src/mscorlib/src/System/ArraySegment.cs')
-rw-r--r-- | src/mscorlib/src/System/ArraySegment.cs | 96 |
1 files changed, 50 insertions, 46 deletions
diff --git a/src/mscorlib/src/System/ArraySegment.cs b/src/mscorlib/src/System/ArraySegment.cs index bc39c2474f..b767e7bd77 100644 --- a/src/mscorlib/src/System/ArraySegment.cs +++ b/src/mscorlib/src/System/ArraySegment.cs @@ -16,6 +16,7 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; +using System.Diagnostics; using System.Diagnostics.Contracts; namespace System @@ -28,10 +29,10 @@ namespace System [Serializable] public struct ArraySegment<T> : IList<T>, IReadOnlyList<T> { - 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) @@ -64,10 +65,10 @@ namespace System { get { - Contract.Assert( (null == _array && 0 == _offset && 0 == _count) + Debug.Assert( (null == _array && 0 == _offset && 0 == _count) || (null != _array && _offset >= 0 && _count >= 0 && _offset + _count <= _array.Length), "ArraySegment is invalid"); - + return _array; } } @@ -83,7 +84,7 @@ namespace System // after reading each field out of an ArraySegment into their stack. Contract.Ensures(Contract.Result<int>() >= 0); - Contract.Assert( (null == _array && 0 == _offset && 0 == _count) + Debug.Assert( (null == _array && 0 == _offset && 0 == _count) || (null != _array && _offset >= 0 && _count >= 0 && _offset + _count <= _array.Length), "ArraySegment is invalid"); @@ -102,19 +103,38 @@ namespace System // after reading each field out of an ArraySegment into their stack. Contract.Ensures(Contract.Result<int>() >= 0); - Contract.Assert( (null == _array && 0 == _offset && 0 == _count) + Debug.Assert( (null == _array && 0 == _offset && 0 == _count) || (null != _array && _offset >= 0 && _count >= 0 && _offset + _count <= _array.Length), "ArraySegment is invalid"); return _count; } } - + + public Enumerator GetEnumerator() + { + if (_array == null) + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray); + Contract.EndContractBlock(); + + return new Enumerator(this); + } + public override int GetHashCode() { - return null == _array - ? 0 - : _array.GetHashCode() ^ _offset ^ _count; + if (_array == null) + { + return 0; + } + + int hash = 5381; + hash = System.Numerics.Hashing.HashHelpers.Combine(hash, _offset); + hash = System.Numerics.Hashing.HashHelpers.Combine(hash, _count); + + // The array hash is expected to be an evenly-distributed mixture of bits, + // so rather than adding the cost of another rotation we just xor it. + hash ^= _array.GetHashCode(); + return hash; } public override bool Equals(Object obj) @@ -174,7 +194,7 @@ namespace System int index = System.Array.IndexOf<T>(_array, item, _offset, _count); - Contract.Assert(index == -1 || + Debug.Assert(index == -1 || (index >= _offset && index < _offset + _count)); return index >= 0 ? index - _offset : -1; @@ -236,7 +256,7 @@ namespace System int index = System.Array.IndexOf<T>(_array, item, _offset, _count); - Contract.Assert(index == -1 || + Debug.Assert(index == -1 || (index >= _offset && index < _offset + _count)); return index >= 0; @@ -259,46 +279,34 @@ namespace System #endregion #region IEnumerable<T> - IEnumerator<T> IEnumerable<T>.GetEnumerator() - { - if (_array == null) - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray); - Contract.EndContractBlock(); - return new ArraySegmentEnumerator(this); - } + IEnumerator<T> IEnumerable<T>.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<T> + public struct Enumerator : IEnumerator<T> { - 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<T> arraySegment) + internal Enumerator(ArraySegment<T> 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() @@ -315,19 +323,15 @@ namespace System { get { - if (_current < _start) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted); - if (_current >= _end) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.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() { |