2011-11-18 10 views
8

Me gustaría poder obtener el estado real o la semilla o lo que sea de System.Random para poder cerrar una aplicación y cuando el usuario la reinicia, simplemente "vuelve a resembrarla" con la almacenada y continúa como si nunca hubiera sido cerrado.¿Hay alguna manera de captar el estado real de System.Random?

¿Es posible?

Utilizando la idea de Jon, se me ocurrió esto para probarlo;

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(); 
} 

Respuesta

10

Es serializable, por lo que es posible que usted sólo puede utilizar BinaryFormatter y guardar la matriz de bytes ...

código

muestra:

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)); 
     } 
    } 
} 

resultados en un análisis de la muestra son prometedores:

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

Es cierto que no estoy interesado en la serialización incorporada, pero si esto es por un tiempo increíblemente rápido y sucio, debería estar bien ...

+0

Voy a intentar de mi lado, voy a mantener un ojo aquí al mismo tiempo – Fredou

+0

gracias :-), funciona bien, no pensé en la serialización :-( – Fredou

+0

al mirar el archivo generado, parece que almacenar todo o parte del número aleatorio generado previamente. Esto podría ser grande. ¿Sabes cómo solucionar este problema? – Fredou

0

No soy un chico C#, así que no tengo los recursos para ver el código fuente, pero la semilla debe almacenarse en la clase. De su documentación, la clase no está sellada, por lo que debería poder hacer una subclase. En esta subclase, puede crear una función para devolver la semilla actual. Al apagar su aplicación, puede guardar la semilla (¿archivo? Base de datos? Monos con buena memoria?) Y luego volver a cargarla cuando inicie su nueva aplicación.

Esto tiene la ventaja adicional de permitirle restaurar desde cualquier punto previamente guardado, con fines de copia de seguridad o algo así.

+0

¿Tiene motivos para creer que la semilla forma parte de la API pública (o protegida) de la clase? La herencia no ayudará si la semilla es un detalle de implementación privada, las clases derivadas no tendrán acceso. –

+0

@Anthony Dije que no tengo el código fuente. Supongo que podría haber sido explícito al decir que no tengo pruebas concluyentes para apoyar eso, así que no, no lo hago. Para mí, parece algo lógico incluir en tu API protegida. – corsiKa

+0

voy a ver esto, ya que no me gusta lo que veo en el archivo guardado de la serialización – Fredou

Cuestiones relacionadas