Каковы последствия выполнения мелкого копирования массива с целью изменения его размера?
-
10-07-2019 - |
Вопрос
Если мое понимание глубокого и поверхностного копирования верно, мой вопрос невозможен.Если у вас есть массив (a[10]) и вы выполняете неглубокую копию (b[20]), разве это не будет невозможно, поскольку данные в b не будут смежными?
Если я понял это совершенно неправильно, может ли кто-нибудь посоветовать быстрый способ имитировать (в С#) способность С++ выполнять перераспределение для изменения размера массива.
ПРИМЕЧАНИЕ
Я смотрю на члены .Clone() и .Copy() объекта System.Array.
Решение
Вы не можете изменить размер существующего массива, однако вы можете использовать:
Array.Resize(ref arr, newSize);
При этом выделяется новый массив, копируются данные из старого массива в новый и обновляется arr
переменная (которая в данном случае передается по ссылке).Это то, что вы имели ввиду?
Однако любой другой ссылки, все еще указывающие на старый массив, не будут обновляться.Лучшим вариантом может быть работа с List<T>
- тогда вам не нужно будет изменять его размер вручную, и у вас не возникнет проблема с устаревшими ссылками.Ты только Add
/Remove
и т. д.Как правило, вы не очень часто используете массивы напрямую.У них есть свое применение, но они не являются стандартными.
Повторите ваши комментарии;
- заниматься боксом:
List<T>
не боксирует.Это один из моментов, касающихся дженериков;под капотом,List<T>
является оберткой вокругT[]
, так чтоList<int>
имеетint[]
- никакого бокса.СтаршийArrayList
является оберткой вокругobject[]
, так что делает коробка;конечно, бокс не так плохо, как вы могли бы предположить в любом случае. - работа
Array.Resize
;насколько я помню, он находит размерфактические детали скрыты внутренним вызовом - но, по сути, после выделения нового массива выполняется копирование (memcpy) данных между двумя массивами, поэтому это должно быть довольно быстро;обратите внимание, что для ссылочных типов копируется только ссылка, а не объект в куче.Однако если вы регулярно меняете размер,T
, затем используетBuffer.BlockCopy
чтобы скопировать содержимоеList<T>
обычно будет намного проще (и быстрее, если только вы не заново реализуете то, чтоList<T>
резервная емкость восстанавливается, чтобы минимизировать количество изменений размера).