Here is a refined version picking up from some of the answers here, just add this to your project.
public class RandomState
{
private static Lazy<System.Reflection.FieldInfo> _seedArrayInfo = new Lazy<System.Reflection.FieldInfo>(typeof(System.Random).GetField("_seedArray", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static));
private static Lazy<System.Reflection.FieldInfo> _inextInfo = new Lazy<System.Reflection.FieldInfo>(typeof(System.Random).GetField("_inext", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static));
private static Lazy<System.Reflection.FieldInfo> _inextpInfo = new Lazy<System.Reflection.FieldInfo>(typeof(System.Random).GetField("_inextp", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static));
private static System.Reflection.FieldInfo seedArrayInfo {get { return _seedArrayInfo.Value; }}
private static System.Reflection.FieldInfo inextInfo { get { return _inextInfo.Value; } }
private static System.Reflection.FieldInfo inextpInfo { get { return _inextpInfo.Value; } }
private int[] seedState;
private int inext;
private int inextp;
public static RandomState GetState(Random random)
{
var state = new RandomState() { seedState = ((int[])seedArrayInfo.GetValue(random)).ToArray(), inext = (int)inextInfo.GetValue(random), inextp = (int)inextpInfo.GetValue(random) };
return state;
}
public static void SetState(Random random, RandomState state)
{
seedArrayInfo.SetValue(random, state.seedState.ToArray());
inextInfo.SetValue(random, state.inext);
inextpInfo.SetValue(random, state.inextp);
}
}
public static class RandomExtensions
{
public static RandomState GetState (this System.Random random)
{
return RandomState.GetState(random);
}
public static void ApplyState (this System.Random random, RandomState state)
{
RandomState.SetState(random, state);
}
}
Example of using it, trying to replicate this.
public class Program
{
public static void Main (string[] args)
{
System.Random rnd = new System.Random (255);
var firststate = rnd.GetState();
Console.WriteLine("Saved initial state...");
PrintRandom ("Step ", rnd);
PrintRandom ("Step ", rnd);
PrintRandom("Step ", rnd);
var oldState = rnd.GetState();
Console.WriteLine("Saved second state....");
PrintRandom ("Step ", rnd);
PrintRandom ("Step ", rnd);
PrintRandom("Step ", rnd);
PrintRandom("Step ", rnd);
PrintRandom("Step ", rnd);
rnd.ApplyState(oldState);
Console.WriteLine("Re-applied second state state....");
PrintRandom ("Step ", rnd);
PrintRandom ("Step ", rnd);
PrintRandom ("Step ", rnd);
PrintRandom ("Step ", rnd);
PrintRandom ("Step ", rnd);
rnd.ApplyState(firststate);
Console.WriteLine("Re-applied initial state state....");
PrintRandom("Step ", rnd);
PrintRandom ("Step ", rnd);
PrintRandom ("Step ", rnd);
}
static void PrintRandom (string label, Random rnd)
{
System.Console.WriteLine(string.Format ("{0} - RandomValue {1}", label, rnd.Next (1, 100)));
}
}
Output:
Saved initial state...
Step - RandomValue 94
Step - RandomValue 64
Step - RandomValue 1
Saved second state....
Step - RandomValue 98
Step - RandomValue 34
Step - RandomValue 40
Step - RandomValue 16
Step - RandomValue 37
Re-applied second state state....
Step - RandomValue 98
Step - RandomValue 34
Step - RandomValue 40
Step - RandomValue 16
Step - RandomValue 37
Re-applied initial state state....
Step - RandomValue 94
Step - RandomValue 64
Step - RandomValue 1