问题
How can I get an IEnumerable
of random values? I'm disappointed the class Random doesn't implement IEnumerable<int>
.
回答1:
Write an extension method that will yield return
new values.
public static IEnumerable<int> GetRandomValues(this Random instance)
{
while(true)
{
yield return instance.Next();
}
}
回答2:
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);
}
回答3:
The some problematic points off having an IEnumerable<int>
instance for the Random class are
- The random generator has infinitely many elements, therefore using the
foreach
construct or an loop over the elements will never terminate. - The
IEnumerator<int>
instance whichgetEnumerator
fromIEnumerable<int>
should return has a functionReset
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,
- Keeping an list of already generated values, this might not be very memory efficient, but at least ensures that it will always return the same values after resetting.
- Keeping the starting seed and when
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
}
}
来源:https://stackoverflow.com/questions/11435285/how-do-you-create-an-enumeration-of-random-values