Каковы последствия выполнения поверхностной копии массива, чтобы изменить его размер? - PullRequest
2 голосов
/ 11 января 2009

Если мое понимание глубокого и мелкого копирования верно, мой вопрос невозможен. Если у вас есть массив (a [10]) и вы выполняете поверхностное копирование (b [20]), не станет ли это невозможным, поскольку данные в b не будут смежными?

Если я все понял неправильно, может кто-нибудь посоветовать быстрый способ имитировать (в c #) способность c ++ делать realloc для изменения размера массива.

Примечание
Я смотрю на члены .Clone () и .Copy () объекта System.Array.

1 Ответ

4 голосов
/ 11 января 2009

Вы не можете изменить размер существующего массива, однако вы можете использовать:

Array.Resize(ref arr, newSize);

Это выделяет новый массив, копирует данные из старого массива в новый массив и обновляет переменную arr (которая передается в этом случае by-ref). Это то, что вы имеете в виду?

Однако любые другие ссылки, все еще указывающие на старый массив, не будут обновлены. Лучшим вариантом может быть работа с List<T> - тогда вам не нужно изменять его размер вручную, и у вас нет проблемы устаревших ссылок. Вы просто Add / Remove и т. Д. Как правило, вы не склонны использовать массивы напрямую очень часто. У них есть свои применения, но они не подходят по умолчанию.


Re ваши комментарии;

  • бокс: List<T> не бокс. Это один из пунктов о дженериках; под капотом List<T> является оберткой вокруг T[], поэтому List<int> имеет int[] - без бокса. Более старый ArrayList является оберткой вокруг object[], поэтому делает коробку; конечно, бокс не так плох, как можно было бы предположить в любом случае.
  • работ Array.Resize; если я вспомню, он находит размер T, а затем использует Buffer.BlockCopy, чтобы переписать содержимое фактические детали скрыты внутренним вызовом - но, по сути, после выделения нового массива это перебор ( memcpy) данных между двумя массивами, поэтому они должны быть довольно быстрыми; обратите внимание, что для ссылочных типов это копирует только ссылку, а не объект в куче. Однако, если вы регулярно изменяете размер, List<T> обычно будет намного проще (и быстрее, если вы не будете в основном повторно реализовывать то, что List<T> резервирует емкость, чтобы минимизировать количество изменений).
...