ArrayList против массива объектов и коллекции T - PullRequest
7 голосов
/ 21 февраля 2009

У меня есть класс Customer (с типичными свойствами клиента), и мне нужно обойтись и связать с данными "порцию" Customer экземпляров. В настоящее время я использую массив Customer, но я также использовал Collection из TList из T, прежде чем я знал о Collection из T). Я хотел бы самый тонкий способ передать этот кусок, используя C # и .NET 3.5.

В настоящее время массив Customer прекрасно работает для меня. Эти данные хорошо связываются и кажутся такими же легкими, как и раньше. Мне не нужны вещи, которые List из T предлагает, а Collection из T все еще кажется излишним. Массив требует, чтобы я знал заранее, сколько Customer s я добавляю к чанку, но я всегда знаю это заранее (например, по заданным строкам на странице).

Я что-то упустил, или массив Customer ОК? Есть ли компромисс, по которому я скучаю?

Кроме того, я предполагаю, что Collection из T делает устаревший слабо набранный ArrayList устаревшим. Я здесь?

Ответы [ 6 ]

11 голосов
/ 21 февраля 2009

Да, Collection<T> (или List<T> чаще) делает ArrayList в значительной степени устаревшим. В частности, я считаю, что ArrayList даже не поддерживается в Silverlight 2.

В некоторых случаях с массивами все в порядке, но их следует считать несколько вредными - они имеют различные недостатки. (Конечно, они лежат в основе реализации большинства коллекций ...) Я бы попал в подробности, но Эрик Липперт делает это намного лучше, чем когда-либо в статье по ссылке. Я бы суммировал это здесь, но это довольно сложно сделать. Это действительно стоит просто прочитать весь пост.

4 голосов
/ 22 февраля 2009

Никто не упомянул совет по Framework Guidelines: Не используйте List<T> в общедоступных API :

Мы не рекомендуем использовать Список в публичные API по двум причинам.

  • List<T> не предназначен для удлинения. то есть вы не можете переопределить любой члены. Это, например, означает, что объект, возвращающий List<T> из недвижимость не сможет получать уведомления когда коллекция будет изменена. Collection<T> позволяет переопределять SetItem защищенный член, чтобы получить «Уведомлено» при добавлении новых товаров или существующий элемент изменен.

  • В списке много участников, которые не имеют отношения ко многим сценариям. Мы скажем, что List<T> слишком "занят" для публичные объектные модели. Представить Возвращение свойства ListView.Items List<T> со всем его богатством. Сейчас, посмотрите на фактический ListView.Items тип возврата; это намного проще и похож на Collection<T> или ReadOnlyCollection<T>

Кроме того, если ваша цель - двусторонняя привязка данных, взгляните на BindingList<T> (с оговоркой, что он не сортируется «из коробки»!)

3 голосов
/ 21 февраля 2009

Как правило, вы должны «обойти» IEnumerable или ICollection (в зависимости от того, имеет ли смысл для вашего потребителя добавлять элементы).

1 голос
/ 22 февраля 2009

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

Однако, если вы не уверены, то лучшим вариантом для вас является коллекция какого-то типа. Какую коллекцию вы выберете, зависит от операций, которые вы хотите с ней выполнить. Коллекции все о вставках, манипуляциях, поисках и удалениях. Если вы делаете частые частые поиски данного элемента, то словарь может быть лучшим. Если вам нужно отсортировать данные, возможно, SortedList будет работать лучше.

Я бы не стал беспокоиться об «легком весе», если вы не говорите о большом количестве элементов, и даже тогда преимущества поиска O (1) перевешивают затраты ресурсов.

Когда вы «передаете» коллекцию, вы передаете только ссылку, которая в основном является указателем. Таким образом, нет никакой разницы в производительности между передачей коллекции и массива.

0 голосов
/ 22 февраля 2009

Я согласен с Аланом, с одним дополнением. Если вы хотите обратиться к возвращаемому значению с помощью индекса myArray [n], используйте IList.

Массив по своей природе поддерживает IList (а также IEnumerable и ICollection, в этом отношении). Таким образом, если вы проходите через интерфейс, вы все равно можете использовать массив в качестве базовой структуры данных. Таким образом, методы, в которые вы передаете массив, не должны «знать», что базовая структура данных является массивом:

        public void Test()
{
    IList<Item> test = MyMethod();
}

public IList<Item> MyMethod()
{
    Item[] items = new Item[] {new Item()};
    return items;
}
0 голосов
/ 22 февраля 2009

Я собираюсь привести несогласный аргумент как к Джону, так и к Эрику Липперту), что означает, что вы действительно очень устали от моего ответа!).

Суть аргументов Эрика Липперта против массивов заключается в том, что содержимое является неизменным, а сама структура данных - нет. Что касается возврата их из методов, содержимое списка так же изменчиво. Фактически, поскольку вы можете добавлять или вычитать элементы из списка, я бы сказал, что это делает возвращаемое значение более изменяемым, чем массив.

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

В любом случае, слушайте Джона и Эрика =), и я согласен, что список почти всегда имеет больше смысла.

...