简体   繁体   中英

How can I enumerate an infinite sequence of integers in C# 4.0?

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.

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.

这发生在我身上,适合我正在做的事情:

Enumerable.Range (0, int.MaxValue)

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM