Кажется, что List<T>
в C # можно делать все, что может делать массив, и даже больше, и кажется, что он также эффективен в памяти и производительности, как и массив.
Так зачем мне использовать массив?
Я явно не спрашиваю о случаях, когда API или другое внешнее ограничение (то есть функция Main) требует от меня использования массива ... Я только спрашиваю о создании новых структур данных в своем собственном коде.
c#
data-types
JoelFan
источник
источник
List<T>
is also just as efficient in memory and performance as an array
- гм. Откуда вы взяли это понятие?var test = new string[5,5]
;)Ответы:
По той же причине я не езжу на грузовике, когда иду на работу. Я не использую то, что я не буду использовать функции.
Прежде всего, массив является примитивной конструкцией, поэтому массив наверняка быстрее и эффективнее, чем List <>, поэтому ваш аргумент неверен. Массив также доступен везде и известен разработчикам, использующим разные языки и платформы.
Самая важная причина, по которой я использую массив вместо List <>, заключается в том, что данные имеют фиксированную длину . Если я не буду добавлять или удалять какие-либо элементы из этой коллекции данных, я хочу убедиться, что тип отражает это.
Еще одна вещь, скажем, вы реализуете новую структуру данных, и вы прочитали несколько статей об этом. Теперь, реализуя конкретные алгоритмы, вы не всегда можете полагаться на чью-либо реализацию типа общего назначения. Он меняется с .NET на Mono и даже между разными версиями фреймворка.
И иногда проще портировать кусок кода, который использует массив вместо фреймворк-зависимого типа.
источник
List<T>
он реализован с использованием массива? Если вы знаете количество элементов заранее (что необходимо знать при использовании массива), вы можете использовать эти знания и при инициализации списка.Конечно, вам нужны массивы для управления вашей коллекцией изменчивых структур , и что бы мы делали без них.
(обратите внимание, что в некоторых случаях желательно, чтобы массив изменяемой структуры был желателен, но обычно это отличающееся поведение изменяемых структур в массивах по сравнению с другими коллекциями является источником ошибок, которых следует избегать)
Более серьезно, вам нужен массив, если вы хотите передать элемент по ссылке . т.е.
Это может быть полезно для беззащитного кода без блокировки.
Вам нужен массив, если вы хотите быстро и эффективно инициализировать вашу коллекцию фиксированного размера значением по умолчанию .
(обратите внимание, что было бы возможно реализовать конструктор для List, который делает то же самое, просто C # не предлагает эту функцию)
вам нужен массив, если вы хотите эффективно копировать части коллекции
(опять же, это то, что может быть реализовано и для List, но эта функция не существует в c #)
источник
Редко у вас будет сценарий, в котором вы знаете, что вам нужно фиксированное количество элементов. С точки зрения дизайна, этого следует избегать. Если вам нужно 3 вещи, характер бизнеса означает, что вам очень часто понадобится 4 в следующем выпуске.
Тем не менее, когда этот редкий сценарий действительно происходит, использование массива для принудительного применения этого инварианта фиксированного размера полезно. Он дает сигнал другим программистам, что он имеет фиксированный размер, и помогает предотвратить неправильное использование, когда кто-то добавляет или удаляет элемент, что нарушает ожидания в других частях кода.
источник
На ваш вопрос уже был дан ответ .
Это не так. Из вопроса я связал:
Массивы в два раза быстрее в некоторых важных случаях. Я уверен, что использование памяти также отличается нетривиально.
Так как основная предпосылка вашего вопроса, таким образом, побеждена, я предполагаю, что это отвечает на ваш вопрос. В дополнение к этому, иногда массивы навязываются вам Win32 API, шейдером вашего GPU или какой-либо другой не-DotNet библиотекой.
Даже в DotNet некоторые методы потребляют и / или возвращают массивы (например,
String.Split
). Это означает, что либо вы теперь должны потреблять стоимость вызововToList
иToArray
все время, либо вы должны согласовывать и использовать массив, возможно, продолжая цикл, передавая это бедным нижестоящим пользователям вашего кода.Больше вопросов и ответов по переполнению стека на эту тему:
List<T>
: когда использовать какой?List<>
?источник
В дополнение к причинам, перечисленным в других ответах, для литерала массива требуется меньше символов для объявления:
Использование массива вместо
List
делает код немного короче и чуть более читабельным в случаях, когда (1) вам нужно передать какой-либоIEnumerable<T>
литерал, или (2), когда другие функцииList
не имеют значения, и вам нужно использовать какой-то список, подобный списку буквальный.Я делал это время от времени в модульных тестах.
источник
foreach( var x in new []{ a, b, c ) ) DoStuff( x )
илиnew []{ a, b, c ).Select( ... )
т. Д.Это строго с точки зрения ОО.
Хотя я не могу придумать причину для передачи всего лишь массива, я, конечно, вижу ситуации, когда представление массива внутри класса, вероятно, является лучшим выбором.
Хотя есть и другие параметры, которые дают сходные характеристики, ни один из них не выглядит столь же интуитивно понятным, как массив для задач, связанных с обработкой перестановок, вложенными в циклы, матричное представление, битовые карты и алгоритмы чередования данных.
Существует значительное количество научных областей, которые широко используют матричную математику. (например, обработка изображений, исправление ошибок в данных, цифровая обработка сигналов, множество прикладных математических задач). Большинство алгоритмов в этих областях написаны с точки зрения использования многомерных массивов / матриц. Поэтому было бы более естественно реализовать алгоритмы по мере их определения, а не делать их более «программными» дружественными за счет потери прямой привязки к документам, на которых основаны алгоритмы.
Как я уже сказал, в этих случаях вы, вероятно, можете избежать использования списков, но это добавляет еще один уровень сложности поверх уже сложных алгоритмов.
источник
Это на самом деле относится и к другим языкам, которые также имеют списки (например, Java или Visual Basic). Есть случаи, когда вам нужно использовать массив, потому что метод возвращает массив вместо List.
В реальной программе я не думаю, что массив будет использоваться очень часто, но иногда вы знаете, что данные будут иметь фиксированный размер, и вам нравится небольшой выигрыш в производительности, который вы получаете от использования массива. Микрооптимизация была бы уважительной причиной, так же как метод, возвращающий список, или необходимость многомерной структуры данных.
источник
list<T>
wherevector<T>
будет работать - ужасно плохая идея в C / C ++.vector<T> x
компилируется нормально для меня в C . :-)list<T>
. По сути, я видел много проблем с производительностью, вызванных разработчиками, которые просто использовали списки по умолчанию, когда массив был лучшим выбором.Ну, я нашел применение для массивов в игре, которую я писал. Я использовал его для создания системы инвентаря с фиксированным количеством слотов. Это имело несколько преимуществ:
Я подумал, что если мне когда-нибудь понадобится «увеличить» размер инвентаря, я мог бы сделать это, перенеся старые элементы в новый массив, но поскольку инвентарь был зафиксирован по экранному пространству, и мне не нужно было динамически увеличивать его. / меньше, он работал хорошо для той цели, для которой я его использовал.
источник
Если вы пересекаете все элементы списка, то нет, массив не нужен, «следующий» или произвольный «выбор без замены» подойдет.
Но если вашему алгоритму необходим произвольный доступ к элементам в коллекции, тогда да, массив необходим.
Это несколько аналогично «нужно ли идти?». На разумном современном языке это вообще не нужно. Но если вы удалите абстракции, в какой-то момент это все, что вам действительно доступно, то есть единственный способ реализовать эти абстракции - использовать функцию «ненужные». (Конечно, аналогия не идеальна, я не думаю, что кто-то говорит, что массивы - плохая практика программирования; их легко понять и подумать).
источник
List<T>
.Устаревшая совместимость.
Все формы личного опыта:
Устаревшие программисты - мой коллега использует массивы повсеместно, работает уже более 30 лет, удачи, передумав с вашими новыми запутанными идеями.
Устаревший код - foo (панель массива []) уверен, что вы можете использовать функцию toarray списка / вектора / коллекции, но если вы не используете какие-либо дополнительные функции, проще начать использовать массив, часто более читаемый без переключения типов.
Унаследованный босс - мой босс был хорошим программистом до того, как много лет назад ушел в управление, и до сих пор считает, что он в курсе, «использовал массивы» и может закончить собрание, объяснив, что такое коллекция может стоить каждому обеду.
источник
1) Нет многомерной версии List. Если ваши данные имеют более одного измерения, использование списков будет очень неэффективным.
2) Когда вы имеете дело с большим количеством небольших типов данных (скажем, с картой, в которой все, что у вас есть, это один байт для типа ландшафта), может быть значительная разница в производительности из-за кэширования. Версия массива загружает несколько элементов за одно чтение памяти, версия списка загружает только один. Кроме того, версия массива содержит в несколько раз больше ячеек в кэше, чем версия списка - если вы неоднократно обрабатываете данные, это может иметь большое значение, если версия массива помещается в кэш, а версия списка - нет.
В крайнем случае рассмотрим Minecraft. (Да, это не написано на C #. По той же причине.)
источник
T[,]
) медленнее, чем эквивалентные зубчатые массивы (напримерT[][]
) .Массив из 100 элементов некоторого типа T инкапсулирует 100 независимых переменных типа T. Если T оказывается типом значения, который имеет изменяемое открытое поле типа Q и одно из типа R, то каждый элемент массива будет инкапсулировать независимые переменные типов Q и R. Таким образом, массив в целом будет инкапсулировать 100 независимых переменных типа Q и 100 независимых переменных типа R; Любая из этих переменных может быть доступна по отдельности, не затрагивая другие. Ни один тип коллекции, кроме массивов, не позволяет использовать поля структур в качестве независимых переменных.
Если вместо этого T оказался типом класса с открытыми изменяемыми полями типа Q и R, то каждый элемент массива содержит единственную ссылку, где угодно в юниверсе, на экземпляр
T
, и если ни один из элементов массива не будет когда-либо быть изменен для идентификации объекта, на который существует какая-либо внешняя ссылка, тогда массив будет эффективно инкапсулировать 100 независимых переменных типа Q и 100 независимых переменных типа R. Другие типы коллекций могут имитировать поведение такого массива, но если это единственная цель массив состоит в том, чтобы инкапсулировать 100 переменных типа Q и 100 типа R, инкапсуляция каждой пары переменных в свой собственный объект класса является дорогостоящим способом сделать это. Дальше,использование массива или коллекции изменяемого типа класса создает вероятность того, что переменные, идентифицируемые элементами массива, могут быть не независимыми .Если тип должен вести себя как какой-то объект, то это должен быть либо тип класса, либо структура частного поля, которая не обеспечивает никаких средств мутации, кроме замены. Однако, если тип должен вести себя как набор связанных, но независимых переменных, склеенных с клейкой лентой, то следует использовать тип, который представляет собой набор переменных, склеенных с клейкой лентой - структура открытого поля , Массивы таких типов очень эффективны для работы и имеют очень чистую семантику. Использование любого другого типа приведет к запутанной семантике, низкой производительности или к тому и другому.
источник
Одним из важных отличий является распределение памяти. Например, обход связанного списка может привести к большим потерям кэша и снижению производительности, в то время как массив представляет собой непрерывный кусок памяти, содержащий несколько экземпляров определенного типа данных, и обход его по порядку с большей вероятностью попадет в ЦП. кэш.
Конечно, массив ссылок на объекты может не так сильно выиграть от попаданий в кэш, поскольку разыменование может все же перенести вас куда-нибудь в память.
Затем есть реализации списка, такие как ArrayList, которые реализуют список с использованием массива. Они полезные примитивы, чтобы иметь.
источник
List<T>
, который реализуется не с помощью связанного списка, а с использованием массива (по сути, это эквивалентноArrayList<T>
Java).Вот некоторые рекомендации, которые вы можете использовать, когда выбирать
Array
и когда выбиратьList
.Array
при возвращении из метода.List
в качестве переменной при создании возвращаемого значения (внутри метода). Затем используйте.ToArray()
при возвращении из метода.В общем, используйте,
Array
когда вы не хотите, чтобы потребитель добавлял элементы в коллекцию. Используйте,List
когда вы хотите, чтобы потребитель добавил элементы в коллекцию.Array
предназначен для работы со «статическими» коллекциями, аList
для работы с «динамическими» коллекциями.источник
Array
вместо нихList
. Приятно слышать ваши мысли, хотя!