我怎样才能得到一个IEnumerable
随机值?我很失望Random类没有实现IEnumerable<int>
。
问问题
519 次
3 回答
8
编写一个将新值的扩展方法。yield return
public static IEnumerable<int> GetRandomValues(this Random instance)
{
while(true)
{
yield return instance.Next();
}
}
于 2012-07-11T14:49:34.980 回答
3
例如,您可以很容易地自己实现这一点
public IEnumerable<int> RandomInts(int below)
{
Random r = new Random();
while (true) yield return r.Next(below);
}
于 2012-07-11T14:50:43.593 回答
1
IEnumerable<int>
有一个Random 类的实例的一些问题点是
- 随机生成器有无限多的元素,因此在元素上使用
foreach
构造或循环将永远不会终止。 - from应该返回的
IEnumerator<int>
实例具有将枚举数重置为集合开头的函数。假设行为正确,这应该返回第一个生成的随机数,因为它是在过去生成的。getEnumerator
IEnumerable<int>
Reset
最后一个问题至少可以通过两种方式解决,
- 保留已生成值的列表,这可能不是非常有效的内存,但至少可以确保它在重置后始终返回相同的值。
- 保持起始种子和何时
Reset
调用一个新的生成器可以用前一个种子实例化。应隐藏 Random 的所有其他随机生成方法,以防止 , 被访问。
由于记账方法不是很好,我会选择第二个版本。这是一个相当大的类,如下所示。
public class RandomInt : IEnumerable<int>
{
int seed;
public RandomInt ()
{
seed = new Random ().Next();
}
public IEnumerator<int> GetEnumerator ()
{
return new InternalEnumerator (seed);
}
protected class InternalEnumerator : IEnumerator<int>
{
Random randomGen;
int current;
int seed;
protected InternalEnumerator (int seed)
{
this.seed = seed;
}
#region IEnumerator implementation
public bool MoveNext ()
{
if (randomGen == null)
randomGen = new Random (seed);
current = randomGen.Next();
return true;
}
public void Reset ()
{
randomGen = null;
}
public int Current {
get {
if (randomGen == null)
throw new InvalidOperationException ("Enumerator in reset state");
return current;
}
}
#endregion
}
}
于 2012-07-11T15:26:39.157 回答