DotNext by .NET Foundation and Contributors

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

 MemoryRental<T>

public struct MemoryRental<T>
Represents the memory obtained from the pool or allocated on the stack or heap.
using System; using System.Buffers; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace DotNext.Buffers { [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public ref struct MemoryRental<[System.Runtime.CompilerServices.Nullable(2)] T> { private readonly object owner; private readonly Span<T> memory; [EditorBrowsable(EditorBrowsableState.Never)] [CLSCompliant(false)] public static int StackallocThreshold { get; } = 1 + LibrarySettings.StackallocThreshold / Unsafe.SizeOf<T>(); [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] public Span<T> Span { [IsReadOnly] [return: System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] get { return memory; } } public bool IsEmpty { [IsReadOnly] get { return memory.IsEmpty; } } public int Length { [IsReadOnly] get { return memory.Length; } } public ref T this[int index] { [IsReadOnly] get { return ref memory[index]; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public MemoryRental([System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] Span<T> span) { memory = span; owner = null; } public MemoryRental([System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] Span<T> span, int length) { this = new MemoryRental<T>(span.Slice(0, length)); } public MemoryRental(MemoryPool<T> pool, int minBufferSize, bool exactSize = true) { ArgumentNullException.ThrowIfNull((object)pool, "pool"); if (minBufferSize <= 0) throw new ArgumentOutOfRangeException("minBufferSize"); IMemoryOwner<T> memoryOwner = pool.Rent(minBufferSize); memory = memoryOwner.Memory.Span; if (exactSize) memory = memory.Slice(0, minBufferSize); owner = memoryOwner; } public MemoryRental(MemoryPool<T> pool) { ArgumentNullException.ThrowIfNull((object)pool, "pool"); IMemoryOwner<T> memoryOwner = pool.Rent(-1); memory = memoryOwner.Memory.Span; owner = memoryOwner; } public MemoryRental(int minBufferSize, bool exactSize = true) { T[] array = ArrayPool<T>.Shared.Rent(minBufferSize); memory = (exactSize ? new Span<T>(array, 0, minBufferSize) : new Span<T>(array)); owner = array; } public static implicit operator MemoryRental<T>([System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] Span<T> span) { return new MemoryRental<T>(span); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [IsReadOnly] [EditorBrowsable(EditorBrowsableState.Never)] public ref T GetPinnableReference() { return ref memory.GetPinnableReference(); } [IsReadOnly] public override string ToString() { return memory.ToString(); } public void Dispose() { object obj = owner; IDisposable disposable = obj as IDisposable; if (disposable == null) { T[] array = obj as T[]; if (array != null) ArrayPool<T>.Shared.Return(array, RuntimeHelpers.IsReferenceOrContainsReferences<T>()); } else disposable.Dispose(); this = default(MemoryRental<T>); } } }