Я анализирую байтовый массив произвольной длины, который будет передан нескольким различным слоям синтаксического анализа. Каждый анализатор создает заголовок и полезную нагрузку пакета, как любая обычная инкапсуляция.
Моя проблема заключается в том, как инкапсуляция удерживает полезную нагрузку массива байтов пакетов. Скажем, у меня есть 100-байтовый массив с тремя уровнями инкапсуляции. Будут созданы три объекта пакета, и я хочу установить полезную нагрузку этих пакетов в соответствующую позицию в байтовом массиве пакета.
Например, допустим, что размер полезной нагрузки равен 20 для всех уровней, а затем представьте, что на каждом объекте есть public byte[] Payload
. Однако проблема в том, что byte[] Payload
является копией исходных 100 байт, поэтому в итоге я получу 160 байт в памяти вместо 100.
Если бы это было в C ++, я мог бы просто использовать указатель - однако я пишу это в C #.
Итак, я создал следующий класс:
public class PayloadSegment<T> : IEnumerable<T>
{
public readonly T[] Array;
public readonly int Offset;
public readonly int Count;
public PayloadSegment(T[] array, int offset, int count)
{
this.Array = array;
this.Offset = offset;
this.Count = count;
}
public T this[int index]
{
get
{
if (index < 0 || index >= this.Count)
throw new IndexOutOfRangeException();
else
return Array[Offset + index];
}
set
{
if (index < 0 || index >= this.Count)
throw new IndexOutOfRangeException();
else
Array[Offset + index] = value;
}
}
public IEnumerator<T> GetEnumerator()
{
for (int i = Offset; i < Offset + Count; i++)
yield return Array[i];
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
IEnumerator<T> enumerator = this.GetEnumerator();
while (enumerator.MoveNext())
{
yield return enumerator.Current;
}
}
}
Таким образом, я могу просто ссылаться на позицию внутри исходного байтового массива, но использовать позиционную индексацию. Однако, если я сделаю что-то вроде:
PayloadSegment<byte> something = new PayloadSegment<byte>(someArray, 5, 10);
byte[] somethingArray = something.ToArray();
Будет ли somethingArray
копией байтов или ссылкой на исходный PayloadSegment
(который, в свою очередь, является ссылкой на исходный массив байтов)?
РЕДАКТИРОВАТЬ: На самом деле после переосмысления я не могу просто использовать новый MemoryStream(array, offset, length)
?