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

Posted

技术标签:

【中文标题】如何在 C# 4.0 中枚举无限的整数序列?【英文标题】:How can I enumerate an infinite sequence of integers in C# 4.0? 【发布时间】:2011-11-10 07:24:06 【问题描述】:

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

我正在做

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

枚举直到limit 的所有方格。我意识到这很有效,但是如果有一个从0 开始计数的内置函数,我更愿意使用它。

【问题讨论】:

为什么那个枚举器会终止?但是如果你觉得需要,可以自己写:msdn.microsoft.com/en-us/library/9k7k7cf0.aspx "infinite" 是相当大的......你有一个特定的数据类型吗? @JohnSaunders 我本来想拥有 jeremy。 想知道您为什么删除了接受标志? 【参考方案1】:

你可以自己滚动。

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

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

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

我对这个编辑有误。

【讨论】:

【参考方案2】:

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

Enumerable.Range (0, int.MaxValue)

【讨论】:

那比无穷小一点。 这远非无限……事实上无限远!见 Daniel whites 的回答。 int和实际使用而言是无限的。 注意:如果 start 大于零,这将不起作用,因为 start + count 需要小于 int.MaxValue。 如果您只是在寻找Enumerable.Range() 的未绑定版本,这是正确的方法。 Range() 没有未绑定版本是有原因的:Int32 的最大值是 int.MaxValue。如果你实际上想要一个未绑定的东西,你应该看到另一个答案,你根本不能使用int。因此,我认为这个问题很模糊,以至于两个答案都是“正确的”。【参考方案3】:

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

    牺牲 int 类型以换取 BigInteger 之类的东西 - 就像在 this answer 中所做的那样。 牺牲“无限”,以便您可以保留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();

【讨论】:

以上是关于如何在 C# 4.0 中枚举无限的整数序列?的主要内容,如果未能解决你的问题,请参考以下文章

如何在部署目标 < 4.0 的项目中仅引用 iOS 4.0 枚举?

如何在没有 ajax 的 select2 4.0 中启用无限滚动

C#资源文件和C#枚举如何结合使用?

如何创建无限可枚举的Times?

在 JSON (C#) 中序列化枚举值 [重复]

c#中怎么编个数组可以存放无限个整数