For testing purposes I\'m creating random numbers with a given seed (i.e. not based on the current time).
Thus the whole program is deterministic.
If someth
There is an alternative solution that (1) avoids the need to remember all previously generated numbers; (2) does not involve accessing the private fields of Random; (3) does not require serialization; (4) does not require looping back through Random as many times as it had been called; and (5) does not require creating a replacement for the built-in Random class.
The trick is to get state by generating a random number, and then reseeding the random number generator to this value. Then, in the future, one can always return to this state by reseeding the random number generator to this value. In other words, we "burn" a number in the random number sequence for the purpose of saving state and reseeding.
The implementation follows. Note that one would access the Generator property to actually generate numbers.
public class RestorableRandom
{
public Random Generator { get; private set; }
public RestorableRandom()
{
Generator = new Random();
}
public RestorableRandom(int seed)
{
Generator = new Random(seed);
}
public int GetState()
{
int state = Generator.Next();
Generator = new Random(state);
return state;
}
public void RestoreState(int state)
{
Generator = new Random(state);
}
}
And here is a simple test:
[Fact]
public void RestorableRandomWorks()
{
RestorableRandom r = new RestorableRandom();
double firstValueInSequence = r.Generator.NextDouble();
int state = r.GetState();
double secondValueInSequence = r.Generator.NextDouble();
double thirdValueInSequence = r.Generator.NextDouble();
r.RestoreState(state);
r.Generator.NextDouble().Should().Be(secondValueInSequence);
r.Generator.NextDouble().Should().Be(thirdValueInSequence);
}