C# RAII

public struct ManagedBuffer<T> : IDisposable
{
    private int length;
    private IMemoryOwner<T> owner;

    public int Length
    {
        get => length;
        set
        {
            if (owner != null)
            {
                if (value > CapacityMemory.Length)
                {
                    using var oldMemory = owner;
                    owner = Pool.Rent(value);
                    oldMemory.Memory.CopyTo(owner.Memory);
                }
            }
            else
            {
                owner = Pool.Rent(value);
            }
            length = value;
        }
    }

    Memory<T> Memory => CapacityMemory[0..length];

    public Span<T> Span => Memory.Span;

    static MemoryPool<T> Pool => MemoryPool<T>.Shared;

    Memory<T> CapacityMemory => owner?.Memory ?? default;

    public ref T this[int index]
    {
        get
        {
            if (length > index)
            {
                length = index + 1;
            }
            return ref Span[index];
        }
    }

    public void Dispose()
    {
        foreach (var item in CapacityMemory.Span)
        {
            (item as IDisposable)?.Dispose();
        }
        owner?.Dispose();
        owner = null;
    }
}

Usage: ToDo.

Previous Post Next Post