Я пытаюсь написать класс Buffer, который позволяет мне писать и считывать из внутреннего буфера List с использованием общих методов. В C++ это не проблема, так как у нас есть хороший доступ к памяти напрямую (memcpy (я знаю, memcpy небезопасен) и т.д.).
Я пробовал следующее:
// private readonly List<byte> _buffer = new List<byte>();
public void Write<T>(T value) where T : byte, short, ushort, int, uint {
_buffer.AddRange(BitConverter.GetBytes(value));
}
... Но в нем говорится, что лучшая перегрузка имеет некоторые недопустимые аргументы (значение).
У меня также есть проблемы с чтением значения типа byte, short, ushort, int или uint. Я мог бы точно определить тип T, а затем использовать класс BitConverter для преобразования байтов, но я уверен, что есть более простой и суровый способ сделать это (чего я еще не обнаружил).
Как реализовать такие методы, чтобы класс был классным и простым?
РЕДАКТИРОВАТЬ:
Чтобы прочитать из буфера, я пробовал следующее:
public T Read<T>(bool moveIndex = true) {
T data = default(T);
var size = Marshal.SizeOf(data);
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.PtrToStructure(ptr, data);
Marshal.Copy(_buffer.ToArray(), _readIndex, ptr, size);
Marshal.FreeHGlobal(ptr);
if (moveIndex) {
_readIndex += size;
}
return data;
}
Но это бросает мне System.ArgumentException в этой строке Marshal.PtrToStructure(ptr, data);
Что-то вроде этого удовлетворит ваши потребности?
public void Write<T>(T value) where T: struct
{
int size = Marshal.SizeOf(value);
var bytes = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(value, ptr, true);
Marshal.Copy(ptr, bytes, 0, size);
Marshal.FreeHGlobal(ptr);
_buffer.AddRange(bytes);
}