如何在C# 4.0中枚举一个无限的整数序列?

10

在C#中是否有一个函数可以返回无限整数序列[0, 1, 2, 3, 4, 5 ...]IEnumerator

我目前正在做的是

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

枚举所有小于limit的平方数。我知道这很有效,但如果有一个内置函数只是从0开始计数,我更愿意使用它。


1
为什么那个枚举器会终止?但如果你认为需要它,你可以自己编写:http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx - John Saunders
4
“无限大”相当庞大……你有特定的数据类型想要使用吗? - Oliver Charlesworth
@JohnSaunders 我的意思是要 Jeremy。 - Daniel A. White
想知道为什么您移除了接受标志? - Daniel A. White
3个回答

14
你可以自行开发。
   IEnumerable<BigInteger> Infinite() {
      BigInteger value = 0;
      while (true) {
        yield return value++;
      }
   }

编辑 为什么不直接将限制传递给Range?这可能会多一个...

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

我对这次编辑做出了错误的判断。


9
这个对我很有帮助,与我正在做的事情相关:

这发生在我身上,并适用于我所做的事情:

Enumerable.Range (0, int.MaxValue)

你可以使用无符号类型来获取更多。 - Daniel A. White
9
那比无限略微小一点。 - Kerrek SB
3
这远非无限...事实上,它是无限遥远的!请参见丹尼尔·怀特的回答。 - cdiggins
1
int 和实际使用而言,它是无限的。 - Jeremy
3
注意:如果 start 大于零,则此方法将不起作用,因为 start + count 必须小于 int.MaxValue。 - Roman Reiner
1
如果你只是想要一个未绑定版本的 Enumerable.Range(),那么这就是正确的方法。Range() 没有未绑定版本的原因是 Int32 的最大值是 int.MaxValue。如果你真的想要一个无限制的东西,你应该看看其他答案,而且你根本不能使用 int。因此,我认为这个问题足够模糊,两个答案都是“正确”的。 - binki

0

正如评论者所指出并在this answer中说明的那样,int类型具有最大和最小边界,因此您实际上不能将其用作无限序列的值类型。但是,您可以做出以下妥协:

  1. BigInteger之类的东西牺牲int类型-就像在this answer中所做的那样。
  2. 牺牲“无限”以便您可以保留int类型。

由于前者已经涵盖了,我将涵盖后者。下面是我用来提供对int值进行枚举的类,如果该枚举超出范围(太高或太低),则会引发异常。我已经对上/下边缘情况进行了单元测试,一切似乎都很好。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接