Reputation: 137594
How can I get an IEnumerable
of random values? I'm disappointed the class Random doesn't implement IEnumerable<int>
.
Upvotes: 1
Views: 585
Reputation: 614
The some problematic points off having an IEnumerable<int>
instance for the Random class are
foreach
construct or an loop over the elements will never terminate.IEnumerator<int>
instance which getEnumerator
from IEnumerable<int>
should return has a function Reset
which resets the enumerator to the begin of the collection. Assuming correct behaviour this should return the first generated random number, as it was generated in the past.The last problem can be solved in at least two ways,
Reset
is called a new generator can be instantiated with the previous seed. All other random generating methods of Random should be hidden to prevent the, from being accessed.As the bookkeeping method is not very good, I would go for the second version. Which is quite a large class, as you can see below.
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
}
}
Upvotes: 1
Reputation: 50114
You can implement this yourself fairly easily, for example
public IEnumerable<int> RandomInts(int below)
{
Random r = new Random();
while (true) yield return r.Next(below);
}
Upvotes: 3
Reputation: 46008
Write an extension method that will yield return
new values.
public static IEnumerable<int> GetRandomValues(this Random instance)
{
while(true)
{
yield return instance.Next();
}
}
Upvotes: 8