using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; internal unsafe class FixedArray : IDisposable where T : unmanaged { private void* _buffer; public int Length { get; private set; } public T this[int i] { get { return ReadElement(_buffer, i); } set { WriteElement(_buffer, i, value); } } public unsafe FixedArray(int length, bool clearMemory = false) { var bufferSize = Marshal.SizeOf() * length; _buffer = (void*)Alloc(bufferSize); if (clearMemory) { Memset(_buffer, 0, bufferSize); } Length = length; } public ref T ByRef(int i) { return ref *(T*)((byte*)_buffer + i * sizeof(T)); } void IDisposable.Dispose() { Free((IntPtr)_buffer); _buffer = null; Length = 0; } private static T ReadElement(void* buffer, int i) { return *(T*)((byte*)buffer + i * sizeof(T)); } private static void WriteElement(void* buffer, int i, T value) { *(T*)((byte*)buffer + i * sizeof(T)) = value; } private unsafe static IntPtr Alloc(int size) { return Marshal.AllocHGlobal(size); } public unsafe static void Free(IntPtr ptr) { if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); } } private unsafe static void Memset(void* ptr, byte value, int count) { Unsafe.InitBlock(ptr, value, (uint)count); } }