2012-12-17 2 views
0

Есть много вопросов, которые задают вопрос о том, как получить подмножество массива на этом сайте, однако никто не получил ответа на вопрос о том, как писать в массив, как если бы он был byte[].Как я ** писать ** в ArraySegment <byte> .Array? Должен ли я использовать небезопасный код?

byte[] bigTargetBytes = new byte[10000]; 

byte[] twentyBytes = sha256.ComputeHash(sourcebytes); // size is 20 bytes, 
// how do I append this to the existing array without copying, using Linq, etc? 

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

ответ

1

Это не совсем понятно, что вы хотите, но я предполагаю, что вы хотите «просмотреть» на массив байтов. В .Net 4.5, вы можете сделать это с ArraySegment<T>:

var a = new byte[100]; 
var s = new ArraySegment<Byte>(a, 9, 90); 

((IList<Byte>)s)[0] = 10; 
Console.WriteLine(a[9]); // writes "10" 

Таким образом, ваш метод Write90Bytes может вернуть ArraySegment<Byte> и тогда вы могли бы работать на том, что в целях в основной массив, который позволит избежать копирования. Обратите внимание, однако, что ArraySegment<T> - System.ValueType, что означает, что его литье на IList<T> повлечет за собой штраф в боксе.

Если производительность критическая, и вам нужно избегать копирования, вы можете также рассмотреть использование указателей в небезопасном контексте, что означает, что ваш метод Write90Bytes может вернуть Byte*, и вы можете затем индексировать его в массив.

EDIT: Теперь, когда я вижу ваше редактирование, вы не можете просто вернуть значение из функции «в» ячейку памяти массива. Вам нужно передать исходный массив в качестве аргумента.

EDIT 2: Вы не можете делать то, что вы просите. Функция ComputeHash возвращает массив, который он сам выделяет. Единственный способ сделать то, что вы хотите, - это то, что ComputeHash взял массив в качестве параметра. Рассмотрим:

// previously defined... 
byte[] bigTargetBytes = new byte[10000];  

// This method doesn't really exist, but if it did it would look like this 
sha256.ComputeHash(sourcebytes, bigTargetBytes, offset); 

Хотя в .NET существуют определенные ограничения на выделение памяти из-за того, что это удалось во время выполнения, это общая картина в любого языка программирования. В разработке C/C++ используется протокол, в котором вы либо передаете предварительно выделенный массив со смещением, либо maxlength для записи, или вы позволяете функции возвращать выделенную память, которую вам тогда поручают освобождать (если вы не вызваны из рамки). Вы не можете просто вернуть значение в существующий буфер.

Помните, однако, что простое копирование 20 байтов из массива GC, выделенного значением ComputeHash, представляет собой очень тривиальную операцию, которую среда выполнения очень эффективно обрабатывает. Время от времени вы не очень чувствительны к периодам паузы в микросекундах, вы не заметите разницы между фактической копией и гипотетической реализацией.

+0

Я действительно хочу написать ArraySegment .Array – LamonteCristo

+0

Этот пример показывает это. Обратите внимание на значение 'a [9]', которое является исходным массивом. – codekaizen

+0

Я использую 'sha256.ComputeHash' и хочу добавить свой вызов к существующим данным. – LamonteCristo

2

I Боюсь, вам придется сделать копию в любом случае. Я предлагаю вам использовать метод Buffer.BlockCopy(), который является самым быстрым.