Skip to content

Instantly share code, notes, and snippets.

@NickStrupat
Last active December 17, 2024 14:53
Show Gist options
  • Save NickStrupat/748aabaf4c9ba127d9919422438246e2 to your computer and use it in GitHub Desktop.
Save NickStrupat/748aabaf4c9ba127d9919422438246e2 to your computer and use it in GitHub Desktop.
Rented
public interface IRented<T> : IDisposable
{
Memory<T> Memory { get; }
Span<T> Span { get; }
}
public static class ArrayPoolExtensions
{
public static IRented<T> GetRented<T>(this ArrayPool<T> pool, int minimumLength, bool clearOnReturn = false)
{
ArgumentNullException.ThrowIfNull(pool);
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(minimumLength);
return new Rented<T>(pool, minimumLength, clearOnReturn);
}
private sealed class Rented<T>(ArrayPool<T> pool, int minimumLength, bool clearOnReturn = false) : IRented<T>
{
private T[]? buffer = pool.Rent(minimumLength);
private T[] GetBuffer() => buffer ?? throw new ObjectDisposedException(GetType().Name);
public Memory<T> Memory => GetBuffer().AsMemory(0, minimumLength);
public Span<T> Span => GetBuffer().AsSpan(0, minimumLength);
~Rented() => Dispose();
public void Dispose()
{
if (buffer is not { } toReturn)
return;
GC.SuppressFinalize(this);
ArrayPool<T>.Shared.Return(toReturn, clearOnReturn);
buffer = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment