<PackageReference Include="System.Memory" Version="4.5.0" />

ReadOnlySpan<T>

public struct ReadOnlySpan<T>
using System.ComponentModel; using System.Diagnostics; using System.Runtime.CompilerServices; namespace System { [DebuggerTypeProxy(typeof(System.SpanDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] [DebuggerTypeProxy(typeof(System.SpanDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] public readonly ref struct ReadOnlySpan<T> { public ref struct Enumerator { private readonly ReadOnlySpan<T> _span; private int _index; [System.Runtime.CompilerServices.IsReadOnly] public ref T Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: System.Runtime.CompilerServices.IsReadOnly] get { return ref _span[_index]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Enumerator(ReadOnlySpan<T> span) { _span = span; _index = -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { int num = _index + 1; if (num < _span.Length) { _index = num; return true; } return false; } } private readonly Pinnable<T> _pinnable; private readonly IntPtr _byteOffset; private readonly int _length; public int Length => _length; public bool IsEmpty => _length == 0; public static ReadOnlySpan<T> Empty => default(ReadOnlySpan<T>); [System.Runtime.CompilerServices.IsReadOnly] public unsafe ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: System.Runtime.CompilerServices.IsReadOnly] get { if ((uint)index >= (uint)_length) System.ThrowHelper.ThrowIndexOutOfRangeException(); if (_pinnable == null) return ref Unsafe.Add<T>(ref Unsafe.AsRef<T>(_byteOffset.ToPointer()), index); return ref Unsafe.Add<T>(ref Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset), index); } } internal Pinnable<T> Pinnable => _pinnable; internal IntPtr ByteOffset => _byteOffset; public static bool operator !=(ReadOnlySpan<T> left, ReadOnlySpan<T> right) { return !(left == right); } [Obsolete("Equals() on ReadOnlySpan will always throw an exception. Use == instead.")] [EditorBrowsable(EditorBrowsableState.Never)] public override bool Equals(object obj) { throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan); } [Obsolete("GetHashCode() on ReadOnlySpan will always throw an exception.")] [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan); } public static implicit operator ReadOnlySpan<T>(T[] array) { return new ReadOnlySpan<T>(array); } public static implicit operator ReadOnlySpan<T>(ArraySegment<T> segment) { return new ReadOnlySpan<T>(segment.Array, segment.Offset, segment.Count); } public Enumerator GetEnumerator() { return new Enumerator(this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan(T[] array) { if (array == null) this = default(ReadOnlySpan<T>); else { _length = array.Length; _pinnable = Unsafe.As<Pinnable<T>>((object)array); _byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan(T[] array, int start, int length) { if (array == null) { if (start != 0 || length != 0) System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); this = default(ReadOnlySpan<T>); } else { if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start)) System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); _length = length; _pinnable = Unsafe.As<Pinnable<T>>((object)array); _byteOffset = System.SpanHelpers.Add<T>(System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment, start); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] [CLSCompliant(false)] public unsafe ReadOnlySpan(void* pointer, int length) { if (System.SpanHelpers.IsReferenceOrContainsReferences<T>()) System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T)); if (length < 0) System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); _length = length; _pinnable = null; _byteOffset = new IntPtr(pointer); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ReadOnlySpan(Pinnable<T> pinnable, IntPtr byteOffset, int length) { _length = length; _pinnable = pinnable; _byteOffset = byteOffset; } [EditorBrowsable(EditorBrowsableState.Never)] [return: System.Runtime.CompilerServices.IsReadOnly] public unsafe ref T GetPinnableReference() { if (_length != 0) { if (_pinnable == null) return ref Unsafe.AsRef<T>(_byteOffset.ToPointer()); return ref Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset); } return ref Unsafe.AsRef<T>(null); } public void CopyTo(Span<T> destination) { if (!TryCopyTo(destination)) System.ThrowHelper.ThrowArgumentException_DestinationTooShort(); } public bool TryCopyTo(Span<T> destination) { int length = _length; int length2 = destination.Length; if (length == 0) return true; if ((uint)length > (uint)length2) return false; ref T src = ref DangerousGetPinnableReference(); ref T dst = ref destination.DangerousGetPinnableReference(); System.SpanHelpers.CopyTo<T>(ref dst, length2, ref src, length); return true; } public static bool operator ==(ReadOnlySpan<T> left, ReadOnlySpan<T> right) { if (left._length == right._length) return Unsafe.AreSame<T>(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference()); return false; } public unsafe override string ToString() { if ((object)typeof(T) == typeof(char)) { if (_byteOffset == MemoryExtensions.StringAdjustment) { object obj = Unsafe.As<object>((object)_pinnable); string text; if ((text = (obj as string)) != null && _length == text.Length) return text; } fixed (char* value = &Unsafe.As<T, char>(ref DangerousGetPinnableReference())) { return new string(value, 0, _length); } } return string.Format("System.ReadOnlySpan<{0}>[{1}]", new object[2] { typeof(T).get_Name(), _length }); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan<T> Slice(int start) { if ((uint)start > (uint)_length) System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); IntPtr byteOffset = System.SpanHelpers.Add<T>(_byteOffset, start); int length = _length - start; return new ReadOnlySpan<T>(_pinnable, byteOffset, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan<T> Slice(int start, int length) { if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start)) System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start); IntPtr byteOffset = System.SpanHelpers.Add<T>(_byteOffset, start); return new ReadOnlySpan<T>(_pinnable, byteOffset, length); } public T[] ToArray() { if (_length == 0) return System.SpanHelpers.PerTypeValues<T>.EmptyArray; T[] array = new T[_length]; CopyTo(array); return array; } [MethodImpl(MethodImplOptions.AggressiveInlining)] [EditorBrowsable(EditorBrowsableState.Never)] internal unsafe ref T DangerousGetPinnableReference() { if (_pinnable == null) return ref Unsafe.AsRef<T>(_byteOffset.ToPointer()); return ref Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset); } } }