Is there a way to grab the actual state of System.

2019-03-19 17:50发布

问题:

I would like to be able to get the actual state or seed or whatever of System.Random so I can close an app and when the user restarts it, it just "reseeds" it with the stored one and continues like it was never closed.

Is it possible?

Using Jon's idea I came up with this to test it;

static void Main(string[] args)
{
    var obj = new Random();
    IFormatter formatter = new BinaryFormatter();
    Stream stream = new FileStream("c:\\test.txt", FileMode.Create, FileAccess.Write, FileShare.None);
    formatter.Serialize(stream, obj);
    stream.Close();
    for (var i = 0; i < 10; i++)
        Console.WriteLine(obj.Next().ToString());

    Console.WriteLine();

    formatter = new BinaryFormatter();
    stream = new FileStream("c:\\test.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
    obj = (Random)formatter.Deserialize(stream);
    stream.Close();
    for (var i = 0; i < 10; i++)
        Console.WriteLine(obj.Next().ToString());

    Console.Read();
}

回答1:

It's serializable, so you may find you can just use BinaryFormatter and save the byte array...

Sample code:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public class Program
{
    public static void Main(String[] args)
    {
        Random rng = new Random();
        Console.WriteLine("Values before saving...");
        ShowValues(rng);

        BinaryFormatter formatter = new BinaryFormatter(); 
        MemoryStream stream = new MemoryStream();
        formatter.Serialize(stream, rng);

        Console.WriteLine("Values after saving...");
        ShowValues(rng);

        stream.Position = 0; // Rewind ready for reading
        Random restored = (Random) formatter.Deserialize(stream);

        Console.WriteLine("Values after restoring...");
        ShowValues(restored);       
    }

    static void ShowValues(Random rng)
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine(rng.Next(100));
        }
    }
}

Results on a sample run are promising:

Values before saving...
25
73
58
6
33
Values after saving...
71
7
87
3
77
Values after restoring...
71
7
87
3
77

Admittedly I'm not keen on the built-in serialization, but if this is for a reasonably quick and dirty hack, it should be okay...



回答2:

I'm not a C# guy, so I don't have the resources to see the sourcecode, but the seed must be stored in the class. From its documentation the class is not sealed, so you should be able to make a subclass. In this subclass, you can create a function to return the current seed. On shutdown of your app, you can save the seed (file? database? monkeys with good memory?) and then load it back up when you start your new app.

This has the added benefit of allowing you to restore from any previously saved point, for backup purposes or something.



标签: c# .net random