在C#中是否有一个函数可以返回无限整数序列[0, 1, 2, 3, 4, 5 ...]
的IEnumerator
?
我目前正在做的是
Enumerable.Range (0, 1000000000).Select (x => x * x).TakeWhile (x => (x <= limit))
枚举所有小于limit
的平方数。我知道这很有效,但如果有一个内置函数只是从0
开始计数,我更愿意使用它。
在C#中是否有一个函数可以返回无限整数序列[0, 1, 2, 3, 4, 5 ...]
的IEnumerator
?
我目前正在做的是
Enumerable.Range (0, 1000000000).Select (x => x * x).TakeWhile (x => (x <= limit))
枚举所有小于limit
的平方数。我知道这很有效,但如果有一个内置函数只是从0
开始计数,我更愿意使用它。
IEnumerable<BigInteger> Infinite() {
BigInteger value = 0;
while (true) {
yield return value++;
}
}
编辑
为什么不直接将限制传递给Range
?这可能会多一个...
Enumerable.Range(0, limit).Select(x => x * x);
我对这次编辑做出了错误的判断。
这发生在我身上,并适用于我所做的事情:
Enumerable.Range (0, int.MaxValue)
int
和实际使用而言,它是无限的。 - JeremyEnumerable.Range()
,那么这就是正确的方法。Range()
没有未绑定版本的原因是 Int32
的最大值是 int.MaxValue
。如果你真的想要一个无限制的东西,你应该看看其他答案,而且你根本不能使用 int
。因此,我认为这个问题足够模糊,两个答案都是“正确”的。 - binki正如评论者所指出并在this answer中说明的那样,int
类型具有最大和最小边界,因此您实际上不能将其用作无限序列的值类型。但是,您可以做出以下妥协:
BigInteger
之类的东西牺牲int
类型-就像在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();
}