9

Is there a function in C# that returns an IEnumerator of the infinite sequence of integers [0, 1, 2, 3, 4, 5 ...]?

I'm currently doing

Enumerable.Range (0, 1000000000).Select (x => x * x).TakeWhile (x => (x <= limit))

to enumerate all squares up to limit. I realize that this is effective, but if there's a built-in function that just counts up from 0, I would prefer to use it.

Jeremy
  • 1
  • 85
  • 340
  • 366

3 Answers3

14

You could roll your own.

   IEnumerable<BigInteger> Infinite() {
      BigInteger value = 0;
      while (true) {
        yield return value++;
      }
   }

Edit Why dont you just pass limit in to Range? This might be off by one...

Enumerable.Range(0, limit).Select(x => x * x);

I was wrong about this edit.

Jeremy
  • 1
  • 85
  • 340
  • 366
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
9

This occurred to me, and is suitable for what I was doing:

Enumerable.Range (0, int.MaxValue)
Jeremy
  • 1
  • 85
  • 340
  • 366
  • You could do unsigned to get more. – Daniel A. White Sep 05 '11 at 00:46
  • 9
    That's a little less than infinity. – Kerrek SB Sep 05 '11 at 00:46
  • 3
    This is far from infinite ... infinitely far in fact! See Daniel whites answer. – cdiggins Sep 05 '11 at 00:50
  • 1
    It's infinite as far as `int` and actual use are concerned. – Jeremy Dec 06 '13 at 21:48
  • 3
    Note: This won't work if start is larger than zero as start + count needs to be smaller than int.MaxValue. – Roman Reiner Oct 13 '15 at 11:57
  • 1
    If you’re just looking for an unbound version of `Enumerable.Range()`, this is the right way to do it. There’s a reason that `Range()` doesn’t have an unbound version: the maximum that `Int32` goes to is `int.MaxValue`. If you *actually* want to have an unbound thing you should see the other answer and you can’t use `int` at all. I thus think that the question is vague enough that both answers are “right”. – binki Sep 08 '16 at 21:12
0

As pointed out by commenters and illustrated in this answer, the int type has max and min bounds, so you can't actually use it as the value type of an infinite sequence. However, you can compromise as follows:

  1. Sacrifice the int type for something like BigInteger - as is done in this answer.
  2. Sacrifice "infinity" so that you can keep the int type.

Since the former has been covered, I'll cover the latter. Below is a class I used to provide enumeration over int values, which will throw an exception if that enumeration gets out of range, either too high or too low. I've unit tested the upper/lower edge cases and it all seems to work fine.

internal class SequentialIntProviderImpl : ISequentialIntProvider
    {
        public int Start { get; }
        public int Step { get; }

        private int _current;

        public SequentialIntProviderImpl(int start, int step)
        {
            Start = start;
            Step = step;
            _current = start;
        }

        public int Next()
        {
            AssertNextIsInBounds();
            _current += Step;
            return _current;
        }

        private void AssertNextIsInBounds()
        {
            AssertNextLeqIntMax();
            AssertNextGeqIntMin();
        }

        private void AssertNextGeqIntMin()
        {
            if (Step < 0)
            {
                int MinAllowableCurrent = int.MinValue - Step;
                if (_current < MinAllowableCurrent)
                {
                    throw new IndexOutOfRangeException($"Current index {_current} plus step {Step} will exceed int Min value");
                }
            }
        }

        private void AssertNextLeqIntMax()
        {
            if(Step > 0)
            {
                int maxAllowableCurrent = int.MaxValue - Step;
                if(_current > maxAllowableCurrent)
                {
                    throw new IndexOutOfRangeException($"Current index {_current} plus step {Step} will exceed int Max value");
                }
            }
        }
    }

/// <summary>
/// Provides iteration over an arithmetic sequence of ints, starting at the given value & increasing by the given step
/// </summary>
public interface ISequentialIntProvider
{
    /// <summary>
    /// Value to start at
    /// </summary>
    int Start { get; }

    /// <summary>
    /// Value by which to increase the sequence at each successive term
    /// </summary>
    int Step { get; }
    
    /// <returns>The next successive term in the sequence</returns>
    int Next();
}
Colm Bhandal
  • 3,343
  • 2
  • 18
  • 29