Click here to Skip to main content
Click here to Skip to main content

Who knows Enumerable.Range(...)?

By , 14 Apr 2013
 

Introduction

I quite often see constructs like:

for(int n = 0; n < len; ++n)
{
   //... some more or less complex conditional control flow...
   n = 5; // causes the loop to never terminate if len is greater than 5
   //... some more code ...
}

This is a legal language construct, but it introduces the danger of non-determinism.

This tip aims to show some deterministic alternatives to that plain for loop.

Using the Code

If you need to loop over some range of integer, consider using the Enumerable.Range[^] based foreach loop instead:

using System.Linq;
...
foreach (int n in Enumerable.Range(0, len))
{
    ...
}

This guarantees that it iterates over all elements in strict sequence. Another benefit is that you cannot assign any other value to the loop variable n. E.g.

foreach (int n in Enumerable.Range(0, len))
{
    n = 5; // Compiler error!
}

Note: Enumerable.Range(...) is not from, to, but from, count:

//
// Summary:
//     Generates a sequence of integral numbers within a specified range.
//
// Parameters:
//   start:
//     The value of the first integer in the sequence.
//
//   count:
//     The number of sequential integers to generate.
//
// Returns:
//     An IEnumerable<Int32> in C# or IEnumerable(Of Int32) in Visual Basic that
//     contains a range of sequential integral numbers.
//
// Exceptions:
//   System.ArgumentOutOfRangeException:
//     count is less than 0.-or-start + count -1 is larger than System.Int32.MaxValue.
public static IEnumerable<int> Range(int start, int count);

Alternatives

One could also build his own iterator functions (see also C# Iterator Pattern demystified[^]). E.g.

public static IEnumerable<int> CountUp(int n, int count)
{
    while (count-- > 0) yield return n++;
}
public static IEnumerable<int> CountDown(int n, int count)
{
    while (count-- > 0) yield return n--;
}

When used like this...

foreach (int n in CountUp(0, 5)) Console.WriteLine(n);
foreach (int n in CountDown(100, 5)) Console.WriteLine(n);

...results in:

0
1
2
3
4
100
99
98
97
96

You can define any complexity of traversing sequence in that function and let the foreach-loop terminate deterministically, based on that sequence.

Advise

Try to avoid plain for (...) loops and replace by some deterministic loop alternative like:

  • foreach( ... Range(...))
  • foreach( ... CountUp(...))
  • etc.

Other alternatives are Linq iterations like Enumerable.Aggregate[^] etc. But these are a bit more advanced.

History

  • 2012-04-18 First version
  • 2012-04-19 Added hand-crafted CountUp/CountDown functions
  • 2013-04-14 Fixed some broken HTML markup in C# code generics

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Andreas Gieriet
eXternSoft GmbH
Switzerland Switzerland
Member
I feel comfortable on a variety of systems (UNIX, Windows, cross-compiled embedded systems, etc.) in a variety of languages, environments, and tools.
I have a particular affinity to computer language analysis, testing, as well as quality management.
 
More information about what I do for a living can be found at my LinkedIn Profile and on my company's web page (German only).

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberAdam Mendoza22 Apr '13 - 23:06 
GeneralRe: My vote of 5memberAndreas Gieriet23 Apr '13 - 12:59 
Generalovercoming "from, count"professionalMatt T Heffron15 Apr '13 - 7:38 
GeneralRe: overcoming "from, count"memberAndreas Gieriet15 Apr '13 - 10:33 
GeneralRe: overcoming "from, count"professionalMatt T Heffron15 Apr '13 - 10:43 
GeneralRe: overcoming "from, count"memberAndreas Gieriet15 Apr '13 - 12:02 
GeneralRe: overcoming "from, count"professionalMatt T Heffron15 Apr '13 - 12:09 
QuestionAnother readability optimizationmemberpaul.vencill15 Apr '13 - 1:09 
AnswerRe: Another readability optimizationmemberAndreas Gieriet15 Apr '13 - 5:50 
GeneralThoughtsmemberPIEBALDconsult14 Apr '13 - 15:30 
GeneralMy vote of 5memberKenneth Haugland3 Sep '12 - 13:53 
GeneralRe: My vote of 5memberAndreas Gieriet3 Sep '12 - 20:21 
GeneralPros and Cons and ...mvpJani Giannoudis18 Apr '12 - 12:26 
GeneralRe: Pros and Cons and ... [modified]memberAndreas Gieriet18 Apr '12 - 21:22 
QuestionYour problem is not the for...mvpPaulo Zemek18 Apr '12 - 9:48 
AnswerRe: Your problem is not the for...memberAndreas Gieriet18 Apr '12 - 10:56 
GeneralRe: Your problem is not the for...mvpPaulo Zemek18 Apr '12 - 14:10 
GeneralRe: Your problem is not the for...memberAndreas Gieriet18 Apr '12 - 18:05 
AnswerRe: Your problem is not the for...memberTimothyP22 Apr '13 - 8:26 
GeneralRe: Your problem is not the for...memberAndreas Gieriet22 Apr '13 - 8:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 15 Apr 2013
Article Copyright 2012 by Andreas Gieriet
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid