В чем разница между IEnumerable и массивами?

Кто-нибудь опишет IEnumerable и в чем разница между IEnumerable и массивом и где его использовать. Вся информация о нем и как его использовать.


person Nishant Kumar    schedule 26.08.2010    source источник
comment
Enums = msdn.microsoft.com/en-us/ library/9b9dty7d%28VS.80%29.aspx Массивы = msdn.microsoft.com/en-us/library/9b9dty7d%28VS.80%29.aspx   -  person Iain Ward    schedule 26.08.2010
comment
@ w69rdy - я думаю, он имел в виду разницу между IEnumerable и массивом.   -  person Alex Paven    schedule 26.08.2010


Ответы (5)


Массив — это набор объектов с заданным размером.

int[] array = [0, 1, 2];

Это делает его очень полезным в ситуациях, когда вы можете захотеть получить доступ к элементу в определенном месте в коллекции, поскольку местоположение в памяти каждого элемента уже известно.

array[1];

Кроме того, размер массива можно вычислить быстро.

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

public IEnumerable<int> Infinite()
{
    int i = 0;
    while(true)
        yield return i++;
}

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

//This line won't do anything until you actually enumerate the created variable
IEnumerable<int> firstTenOddNumbers = Infinite().Where(x => x % 2 == 1).Take(10);

Однако единственный способ получить конкретный элемент — начать с самого начала и перейти к нужному элементу. Это будет значительно дороже, чем получение элемента из предварительно сгенерированного массива.

Конечно, вы можете перечислять через массив, поэтому массив реализует интерфейс IEnumerable.

person Martin Harris    schedule 26.08.2010
comment
+1 Тщательный ответ ... хотя 2147483647 вряд ли бесконечно. ;) - person Dan J; 26.08.2010
comment
@djacobson Это бесконечно, просто оно не непрерывно. Следующее значение -2147483648... :) - person Martin Harris; 26.08.2010
comment
Бесконечность зависит от настроек компилятора. - person nawfal; 28.01.2014

В .NET неправильно назван интерфейс IEnumerable — он должен быть IIterable. В основном System.Collection.IEnumerable или (начиная с дженериков) System.Collection.Generic.IEnumerable позволяет вам использовать foreach для объекта, реализующего эти интерфейсы.

(Примечание: на самом деле .NET использует утиную типизацию для foreach, поэтому вам не требуется реализовывать эти интерфейсы — достаточно, если вы предоставите подходящие реализации методов.)

Массив (System.Array) — это тип последовательности (где под последовательностью я подразумеваю итерируемую структуру данных, то есть все, что реализует IEnumerable), с некоторыми важными отличиями.

Например, IEnumerable может быть — и часто — отложенной загрузкой. Это означает, что пока вы явно не повторите его, элементы не будут созданы. Это может привести к странному поведению, если вы об этом не знаете. Как следствие, IEnumerable не может сообщить вам, сколько элементов он содержит, пока вы фактически не выполните итерацию по нему (что делает метод расширения Count в классе System.Linq.Enumerable).

У массива есть свойство Length, и с этим мы подошли к самому важному отличию: массив представляет собой последовательность фиксированных (и известных) элементов. Он также предоставляет индексатор, поэтому вы можете удобно получать доступ к его элементам, фактически не перебирая их.

И для справки: «настоящие» перечисления в .NET — это типы, определенные с помощью ключевого слова enum. Они позволяют вам выражать выбор без использования магических чисел или строк. Их также можно использовать в качестве флагов, если они помечены атрибутом FlagsAttribute.

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

person ShdNx    schedule 26.08.2010
comment
Терминология, используемая в .Net, прекрасно подходит. Из en.wikipedia.org/wiki/Enumeration: В математике и теоретической информатике самые широкие а наиболее абстрактное определение перечисления множества — это точное перечисление всех его элементов. То, что вы называете реальными перечислениями, более правильно называть перечисляемыми типами: en.wikipedia.org/wiki/Enumerated_type - person Gabe; 08.09.2010

Массив — это набор данных. Подразумевается, что элементы хранятся непрерывно и могут быть добавлены напрямую.

IEnumerable — это описание набора данных. Сами по себе они не коллекции. В частности, это означает, что коллекцию можно проходить по одному элементу за раз.

ЕСЛИ вы определяете переменную как тип IEnumerable, тогда она может ссылаться на коллекцию любого типа, который соответствует этому описанию.

Массивы перечислимы. Так же как и списки, словари, наборы и другие типы коллекций. Кроме того, вещи, которые не кажутся коллекцией, могут быть Enumerable, например, строка (то есть IEnumerable<char>) или объект, возвращаемый Enumerable.Range(), который генерирует новый элемент для каждого шага, фактически нигде его не удерживая.

person James Curran    schedule 26.08.2010

Массивы

Массив .Net — это набор нескольких значений, последовательно хранящихся в памяти. К отдельным элементам в массиве можно получить произвольный доступ по индексу (и это довольно эффективно). Важными элементами массива являются:

  • this[Int32 index] (оператор индексации)
  • Length

C# имеет встроенную поддержку массивов, и их можно инициализировать непосредственно из кода:

var array = new[] { 1, 2, 3, 4 };

Массивы также могут быть многомерными и реализовывать несколько интерфейсов, включая IEnumerable<T> (где T — тип элемента массива).

IEnumerable‹T›

Интерфейс IEnumerable<T> определяет метод GetEnumerator(), но этот метод редко используется напрямую. Вместо этого для повторения перечисления используется цикл foreach:

IEnumerable<T> enumerable = ...;
foreach (T element in enumerable)
  ...

Если перечисление выполняется для массива или списка, все элементы в перечислении существуют во время перечисления, но также возможно перечисление элементов, которые создаются на лету. Для этого очень полезна конструкция yield return.

Можно создать массив из перечисления:

var array = enumerable.ToArray();

Это позволит получить все элементы из перечисления и сохранить их последовательно в одном массиве.

Подвести итог:

  • Массивы представляют собой набор элементов, к которым можно получить произвольный доступ по индексу.
  • Перечисления — это абстракция набора элементов, к которым можно обращаться один за другим в прямом направлении.
person Martin Liversage    schedule 26.08.2010

Во-первых, массивы обеспечивают произвольный доступ к некоторому содержимому фиксированного размера. Где интерфейс IEnumerable предоставляет данные последовательно, которые вы можете извлекать из IEnumerable по одному, пока источник данных не будет исчерпан.

person Chris Taylor    schedule 26.08.2010