Когда использовать ArrayList над массивом [] в c #? - PullRequest
34 голосов
/ 05 января 2009

Я часто использую ArrayList вместо «нормального» * ​​1002 *.

Мне кажется, что я обманываю (или ленюсь), когда использую ArrayList, когда можно использовать ArrayList над массивом?

Ответы [ 11 ]

60 голосов
/ 05 января 2009

Массивы строго типизированы и хорошо работают в качестве параметров. Если вы знаете длину вашей коллекции и она фиксирована, вам следует использовать массив.

ArrayLists не являются строго типизированными, каждая вставка или повторная попытка нуждаются в приведении к вашему первоначальному типу. Если вам нужен метод для получения списка определенного типа, ArrayLists не дотягивают, потому что вы можете передать ArrayList, содержащий любой тип. ArrayLists используют динамически расширяемый массив для внутреннего использования, поэтому существует также хит для увеличения размера внутреннего массива, когда он достигает своей емкости.

Что вы действительно хотите использовать, так это общий список типа List<T>. Это имеет все преимущества Array и ArrayLists. Он строго типизирован и поддерживает переменную длину элементов.

14 голосов
/ 05 января 2009

В дополнение к ответам Боба и Фредерика я хотел бы отметить, что, хотя массивы имеют ковариацию, общие списки - нет. Например, массив типа MyChildClass[] может быть легко приведен к MyParentClass[], в то время как List<MyChildClass> не может быть приведен к List<MyParentClass>, по крайней мере, не напрямую.

Если вам нужна ковариация, либо используйте массивы, используйте метод Cast () LINQ или какие-либо другие средства, чтобы кастовать каждый элемент по отдельности или дождитесь C # 4 .

7 голосов
/ 05 января 2009

Еще одна мысль здесь - мутация; массив (T[]) является полностью изменяемым и не может быть защищен. List<T> не предоставляет никаких полезных точек расширения, но такие вещи, как Collection<T> (или многие другие реализации IList<T>), позволяют добавлять код, например, для проверки элементов перед их добавлением; аналогично, вы можете иметь только для чтения IList<T> реализаций, что полезно для безопасности потоков, где желательна неизменность.

Я склонен использовать массивы либо во внутренней логике метода (возможно, в качестве локальной переменной), либо в качестве params аргументов, либо в нескольких высоко оптимизированных случаях, когда я знаю длину элементов и знаю код выбирает не изменять его (как личное поле). Кроме этого, List<T> и т. Д., Как правило, более распространены, так как они имеют гораздо меньше накладных расходов при добавлении / удалении элементов.

5 голосов
/ 05 января 2009

Если эта часть кода не является абсолютно критичной для производительности, использование ArrayList прекрасно.

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

Еще лучше, где бы вы ни использовали ArrayList, используйте вместо него универсальную коллекцию List<T>. Он напечатан сильнее, чем первый.

1 голос
/ 05 января 2009

Fabulous Adventures In Coding написал кусок Массивы считаются несколько вредными Это действительно интересное чтение.

1 голос
/ 05 января 2009

Я отвечаю на это с точки зрения Java, но это та же самая основная проблема. Вы не должны чувствовать вину, используя более высокие абстракции. В конце концов, вы используете String s вместо char[] или даже byte[]? Я бы даже предложил пойти еще дальше и по возможности использовать интерфейс List. Единственная причина для того, чтобы сделать один шаг вниз, это соображения производительности.

Использование высшей коллекции абстракций имеет много преимуществ. Вы можете добавить декораторы, чтобы сделать список доступным только для чтения, сделать его фиксированным размером, проверить элементы, которые входят или выходят из коллекции, или используют представления (см. GetRange в C # и subList в Java).

Кстати, ArrayList всегда должен основываться на примитивном массиве, иначе имя будет неправильным. Операции обычно реализуются так, как вы ожидаете при использовании примитивного массива. Если используется связанный список, его обычно называют просто - LinkedList. Это также является преимуществом использования интерфейса: позже вы можете передумать об используемой реализации.

Есть несколько вещей, которые делают использование коллекций неуклюжим. Одно предостережение состоит в том, что коллекции обычно основаны на объектах, и языки имеют значительный разрыв между примитивными и объектными типами. Ограниченные дженерики тоже мало помогают. Тем не менее, я рекомендую коллекции над массивами, если нет веской причины.

Для значений примитивов вы также можете использовать библиотеку примитивов, например GNU Trove . Не знаю, есть ли что-нибудь подобное для C #.

0 голосов
/ 28 октября 2014

Это так.

using System;
using System.Collections;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            //ArrayList
            /*
             An ArrayList doesn't use a LinkedList as the internal data structure! .we can store any type of objects      
             */
            ArrayList list = new ArrayList();
            list.Add("1"); // not strongly type,you can enter any object types (int,string decimals, etc..)
            list.Add(1);
            list.Add(1.25);

            //Array
            /*
             must declare length.
             */
            string[] array = new string[3]; // you must declare object types
            array[0] = "1";
            //array[1] = 1; this get error becoz array is storngly typed. // this print empty value when you run it
            array[2] = "stongly typed";
            Console.WriteLine("------- ARRAYLIST ITEMS ---------");
            foreach (var i in list) {
                Console.WriteLine(i);
            }

            Console.WriteLine("--------- ARRAY ITEMS -----------");
            foreach (var i in array)
            {
                Console.WriteLine(i);
            }

            Console.ReadKey(); 
        }
    }
}
0 голосов
/ 06 февраля 2013

Если вам нужен массив примитивных типов, используйте Array для лучшей производительности, поскольку это позволит избежать автобоксирования и распаковки. Но только если вы заранее знаете размер, который хотите.

0 голосов
/ 05 января 2009

Размер массива является статическим, поэтому, если вы знаете размер во время разработки, используйте массив. Он должен работать быстрее, но я сам не проверял. Если вам нужно часто менять количество объектов (добавляя или удаляя объекты из коллекции), используйте ArrayList или лучше универсальный List из .NET 2. Его также проще использовать, поэтому, если производительность не имеет решающего значения, вы всегда можете использовать List.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...