Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thoughts on foreach with Enumerable.Range vs traditional for loop

In C# 3.0, I'm liking this style:

// Write the numbers 1 thru 7 foreach (int index in Enumerable.Range( 1, 7 )) {     Console.WriteLine(index); } 

over the traditional for loop:

// Write the numbers 1 thru 7 for (int index = 1; index <= 7; index++) {     Console.WriteLine( index ); } 

Assuming 'n' is small so performance is not an issue, does anyone object to the new style over the traditional style?

like image 455
Marcel Lamothe Avatar asked May 27 '09 13:05

Marcel Lamothe


People also ask

Is a foreach loop more efficient than a for loop?

The forloop is faster than the foreach loop if the array must only be accessed once per iteration.

What does enumerable range do?

Enumerable.Take Method (System.Linq)Returns a specified number of contiguous elements from the start of a sequence.

Is for of faster than foreach?

forEach is almost the same as for or for..of , only slower. There's not much performance difference between the two loops, and you can use whatever better fit's the algorithm.


2 Answers

I find the latter's "minimum-to-maximum" format a lot clearer than Range's "minimum-count" style for this purpose. Also, I don't think it's really a good practice to make a change like this from the norm that is not faster, not shorter, not more familiar, and not obviously clearer.

That said, I'm not against the idea in general. If you came up to me with syntax that looked something like foreach (int x from 1 to 8) then I'd probably agree that that would be an improvement over a for loop. However, Enumerable.Range is pretty clunky.

like image 124
mqp Avatar answered Oct 11 '22 01:10

mqp


This is just for fun. (I'd just use the standard "for (int i = 1; i <= 10; i++)" loop format myself.)

foreach (int i in 1.To(10)) {     Console.WriteLine(i);    // 1,2,3,4,5,6,7,8,9,10 }  // ...  public static IEnumerable<int> To(this int from, int to) {     if (from < to)     {         while (from <= to)         {             yield return from++;         }     }     else     {         while (from >= to)         {             yield return from--;         }     } } 

You could also add a Step extension method too:

foreach (int i in 5.To(-9).Step(2)) {     Console.WriteLine(i);    // 5,3,1,-1,-3,-5,-7,-9 }  // ...  public static IEnumerable<T> Step<T>(this IEnumerable<T> source, int step) {     if (step == 0)     {         throw new ArgumentOutOfRangeException("step", "Param cannot be zero.");     }      return source.Where((x, i) => (i % step) == 0); } 
like image 40
LukeH Avatar answered Oct 11 '22 03:10

LukeH