Как пройти через коллекцию, поддерживающую IEnumerable?

Ответы:

155

Подойдет обычный для каждого:

foreach (var item in collection)
{
    // do your stuff   
}
Фредрик Мёрк
источник
Это быстрее, чем .ElementAt (). К сожалению, мой голос заблокирован ответом Алексы, поэтому я не могу его отменить, но это лучший ответ. +1
Лео Гурдиан
Так как же тогда исправить «Возможное множественное перечисление IEnumerable»?
SharpC
1
@SharpC: самый простой способ - вытащить результат в List <T> или массив, а затем передать его в различные места, которые необходимо перебрать. Это гарантирует, что (потенциально дорогое) перечисление результата происходит только один раз, но за счет сохранения результата в памяти. Моим первым шагом было бы выяснить, действительно ли множественное перечисление является проблемой или нет.
Fredrik
94

Наряду с уже предложенными методами использования foreachцикла, я подумал, что я также упомянул, что любой объект, который реализует, IEnumerableтакже предоставляет IEnumeratorинтерфейс через GetEnumeratorметод. Хотя в этом методе обычно нет необходимости, его можно использовать для ручного перебора коллекций и особенно полезно при написании собственных методов расширения для коллекций.

IEnumerable<T> mySequence;
using (var sequenceEnum = mySequence.GetEnumerator())
{
    while (sequenceEnum.MoveNext())
    {
        // Do something with sequenceEnum.Current.
    }
}

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

Нолдорин
источник
7
Не забудьте избавиться от счетчика.
Эрик Липперт,
@Eric: Ага, я добавлю это, потому что его легко пропустить.
Нолдорин,
1
Я думаю, что это будет работать только для объектов IEnumerable <T>, а не для IEnumerable. У меня был общий случай, когда мне пришлось выполнить приведение к IEnumerable, и, следовательно, у меня не было доступного метода GetEnumerator. В любом случае, хорошо для большинства случаев.
Fabio Milheiro
50

или даже очень классический старомодный метод

IEnumerable<string> collection = new List<string>() { "a", "b", "c" };

for(int i = 0; i < collection.Count(); i++) 
{
    string str1 = collection.ElementAt(i);
    // do your stuff   
}

возможно, вам тоже понравится этот метод :-)

Алекса Адриан
источник
9
Почему у него так много голосов? Это будет перечислимое 2n раз вместо одного.
Роман Райнер
1
@RomanReiner, потому что это работает, некоторые люди не беспокоятся о производительности :)
Khateeb321
@RomanReiner, это хороший пример, мне нужно назначить каждый элемент одной коллекции другой коллекции, я думаю, что не могу сделать это с помощью foreach
AminM
1
Если вы посмотрите на реализацию ElementAt, вы обнаружите, что если коллекция является IList, они возвращают элемент по индексу с помощью []; такая же производительность, как у [], однако; в противном случае они получат Enumerator и начнут итерацию, последовательно ища элемент перед его возвратом, поэтому в основном для каждого элемента они создают новый перечислитель и снова перемещаются по списку ...
Израиль Гарсия
1
Хуже всего то, что IEnumerable не поддерживает Count () или ElementAt (). Я думаю, он думает о IList. Это вообще не отвечает на вопрос.
Krowe
8
foreach (var element in instanceOfAClassThatImplelemntIEnumerable)
{

}
Дарин Димитров
источник
0

Возможно, вы забыли об ожидании перед возвратом своей коллекции

Элиальбер Лопес
источник