119

How to loop through a collection that supports IEnumerable?

Alexa Adrian
  • 1,778
  • 2
  • 23
  • 38
mrblah
  • 99,669
  • 140
  • 310
  • 420

5 Answers5

184

A regular for each will do:

foreach (var item in collection)
{
    // do your stuff   
}
Fredrik Mörk
  • 155,851
  • 29
  • 291
  • 343
  • This is faster than .ElementAt(). Unfortunately, my vote is locked in on Alexa's answer so I can't undo it but this is the best answer. +1 – Leo Gurdian Nov 22 '16 at 17:24
  • So how do you then fix "Possible multiple enumeration of IEnumerable"? – SharpC Jun 20 '19 at 09:19
  • 2
    @SharpC: the easiest way is to pull out the result into a List or an array, and then pass that to the various places that needs to iterate over it. This guarantees that the (potentially expensive) enumeration of the result happens only once, but at the cost of storing the result in memory. My first step would be to find out whether the multiple enumeration actually is a problem or not. – Fredrik Mörk Jun 20 '19 at 13:53
116

Along with the already suggested methods of using a foreach loop, I thought I'd also mention that any object that implements IEnumerable also provides an IEnumerator interface via the GetEnumerator method. Although this method is usually not necessary, this can be used for manually iterating over collections, and is particularly useful when writing your own extension methods for collections.

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

A prime example is when you want to iterate over two sequences concurrently, which is not possible with a foreach loop.

Philip Bijker
  • 4,955
  • 2
  • 36
  • 44
Noldorin
  • 144,213
  • 56
  • 264
  • 302
55

or even a very classic old fashion method

using System.Collections.Generic;
using System.Linq;
...

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   
}

maybe you would like this method also :-)

Alexa Adrian
  • 1,778
  • 2
  • 23
  • 38
  • 18
    Why does this have so many upvotes? This will enumerate the enumerable 2n times instead of once. – Roman Reiner Oct 27 '16 at 07:33
  • 2
    @RomanReiner because this works, some people don't bother about the performance :) – Khateeb321 Nov 17 '16 at 14:53
  • @RomanReiner this is good example,i need to assign each element of one Collection to another collection,i think i cant do this using foreach – AminM Feb 18 '17 at 12:50
  • @AminM If you need an index Linq has a Select overload that provides it. Or put i=0 before the foreach and i++ inside the loop body. All better than using ElementAt inside a for loop to iterate an enumerable. – Roman Reiner Feb 24 '17 at 13:07
  • 2
    If you look at the implementation of ElementAt you will find out that if the collection is a IList they return the element at the index using []; so same performance as [], however; if not, they will get Enumerator and start an iteration sequentially looking for the element before returning it, so basically for each element they create a new enumerator and navigate the list again... – Israel Garcia May 30 '17 at 22:13
  • Not Recommended at all. As in each loop it will iterate to the index iterating each element encountered in between. – soan saini Jan 02 '19 at 02:45
  • 3
    It's worse than all that, IEnumerable doesn't support Count() or ElementAt(). I think he's thinking of an IList. This doesn't actually answer the question at all. – krowe Mar 16 '19 at 06:41
  • This also defeats the purpose of [yield](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/yield) (if that's used), which is a frequent scenario when a function returns an IEnumerable. – Shishir Gupta Aug 17 '20 at 14:36
  • This doesn't work for IEnumerable, only for IEnumerable. Those are very different things. – Aashishkebab Oct 12 '21 at 18:20
  • ! This is O(n^2). It will work fine for short sequences but will be bad when sequences grow large. – Johan Franzén Oct 15 '21 at 09:47
8
foreach (var element in instanceOfAClassThatImplelemntIEnumerable)
{

}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
-2

You might also try using extensions if you like short code:

namespace MyCompany.Extensions
{
    public static class LinqExtensions
    {
        public static void ForEach<TSource>(this IEnumerable<TSource> source, Action<TSource> actor) { foreach (var x in source) { actor(x); } }
    }
}

This will generate some overhead, for the sake of having stuff inline.

collection.Where(item => item.IsReady).ForEach(item => item.Start());
Luc Bloom
  • 1,120
  • 12
  • 18
  • I don't know why this got -3 votes, could someone explain why this answer is so bad? – Luc Bloom Sep 04 '22 at 01:31
  • 1
    This is the same as `foreach` — which two answers already suggest — because, of course, that's exactly what it uses, except that won't be obvious to the caller. As you say, there is some overhead to doing it this way, but for what benefit? It doesn't seem all that much shorter than writing a `foreach` loop (less lines?), and it seems you'd only use this for one-liner loop bodies, so why bother? I wouldn't say this is necessarily "so bad", but I wouldn't call it "good", either. – Lance U. Matthews Sep 04 '22 at 02:28