2009-06-01 2 views
0

Рассмотрим следующий метод (используется в фабричный метод):Как сделать маркер из массива Subset [] в управляемом коде?

private Packet(byte[] rawBytes, int startIndex) 
{ 
    m_packetId = BitConverter.ToUInt32(rawBytes, startIndex); 
    m_dataLength = BitConverter.ToUInt16(rawBytes, startIndex + 4); 
    if (this.Type != PacketType.Data) 
     return; 
    m_bytes = new byte[m_dataLength]; 
    rawBytes.CopyTo(m_bytes, startIndex + Packet.HeaderSize); 
} 

Последние две строки кода ударить меня расточительным. Выделение большего объема памяти и заполнение ее значениями из памяти кажутся глупыми.

С неуправляемым кодом, что-то, как это возможно:

m_bytes = (rawBytes + (startIndex + Packet.HeaderSize)); 

(я не запустить его через компилятор так синтаксис, вероятно, выключен, но вы можете видеть, что это всего лишь вопрос манипуляции указателя.)

Я столкнулся с аналогичной проблемой на днях, когда API возвратил массив byte [], который был действительно коротким [] массивом.

Являются ли эти типы перестановок массива просто стоимостью использования управляемого кода или есть новая школа мышления, которую я просто пропустил?

Заранее спасибо.

ответ

2

Рассматривали ли вы реструктуризацию, чтобы, возможно, копия не нужна?

Первый вариант: сохранить ссылку на rawBytes в m_bytes и сохранить смещение, которое необходимо добавить ко всем обращениям к этому массиву байтов.

Второй вариант: make m_bytes a MemoryStream вместо этого, построенный из буфера, смещение и длина; этот конструктор также не копирует буфер байта и просто разрешает доступ к указанному подсегменту.

Имейте в виду, что цена, исключающая операцию копирования, заключается в том, что rawBytes и m_bytes (массив или поток) будут псевдонимами, поэтому изменения в них тоже изменят.

0

Да, это более дорогостоящий в управляемом коде, но нет ничего, что мешает вам сделать этот метод unsafe и выполнять манипуляции с указателями, которые вы хотите сделать.

Смежные вопросы