2009-10-28 10 views
5

Digamos que tengo classA que contiene classB y ambos son [Serializable].¿Cómo cambiar el orden de deserialización usando BinaryFormatter en C#?

Supuse que en la clase de deserialización B se deserializaría primero.

Sin embargo, este no es el caso, ya que pude confirmar con solo iniciar sesión cuando se activaron todos los métodos [OnDeserialized].

ahora tengo el siguiente problema:

Después de deserialización classA se haya completado, se supone que debe erigirse, utilizando los valores de ClassB. Desafortunadamente, classB no se ha deserializado todavía en este punto, por lo que classA se configura mal.

Mi problema se resolvería, si pudiera forzar a BinaryFormatter a deserializar classB antes de claseA, o resolver el Object Graph de abajo hacia arriba en lugar de hacia arriba.

Otra solución obvia sería hacer que classB active un evento cuando se deserialice y luego tener ClassA configurado, pero quiero evitar esta solución no elegante.

Así que agradecería si alguien sabe de una solución mejor.

+0

¿Qué plataforma está utilizando? – Lazarus

+0

De acuerdo con el título de la pregunta, C# -> reticulado – pyrocumulus

Respuesta

3

Si usted tiene que tener el control explícito sobre el orden de los objetos de la serialización y deserialización, le sugiero que implementa la interfaz ISerializable para A:

public class ClassA : ISerializable 
{ 
    private ClassB _dependency; 

    public ClassA(SerializationInfo information, StreamingContext context) 
    { 
     _dependency 
      = (ClassB)information.GetValue("_dependency", typeof(ClassB)); 

     // TODO: Get other values from the serialization info. 
     // TODO: Set up stuff from dependent object. 
    } 

    public SerializationInfo GetObjectData() 
    { 
     information.AddValue("_dependency", _dependency, typeof(ClassB)); 

     // TODO: Add other fields to the serialization info. 
    } 
} 
+0

Gracias, eso funcionaría.La única desventaja es que para hacer un pequeño ajuste (cambiar el orden de deserialización), tengo que obtener manualmente todos los demás objetos/campos en mi clase también. Mientras tanto, utilicé la solución no tan elegante (mediante activación de eventos) como se describe en mi pregunta. Supongo que me quedaré con él, ya que esta solución parece ser aún más simple que la solución detallada de obtener los datos del objeto a mano. –

+0

@Thorsten Lorenz: ¿Encontraste alguna otra solución después de todo? –

1

Sugeriría utilizar un método marcado con [OnDeserialized] para manejar cualquier inicialización posterior a la serialización que requiera y no preocuparse por el orden en que se deserializaron.

+0

No sé si entendiste mi pregunta correctamente, como explica, que sí tengo que ocuparme del orden de deserialización porque de lo contrario mis objetos no se restaurarán correctamente. –

+0

Obviamente debo tener. ¿Puede explicar exactamente qué debe suceder entre A y B que no puede ser manejado por un evento de serialización posterior? –

+0

Los detalles no importan, creo que lo expliqué con claridad: "Después de que la deserialización de la clase A haya finalizado, se supone que debe establecerse a sí misma, utilizando valores de la clase B". Estos valores solo se establecen una vez que la clase B se ha deserializado por completo. –

0

Estos dos pasos podrían hacer el truco:

  1. Haga que el método [OnDeserialized] de classB sea seguro para llamar varias veces.
  2. En el método [OnDeserialized] de classA, llame explícitamente al método [OnDeserialized] en el objeto classB contenido.

El BinaryFormatter va a terminar la llamada al método [OnDeserialized] en el objeto ClassB de nuevo, pero el paso 1 hace que seguro.

1

Puede hacer que classA implemente la interfaz IDeserializationCallback. Su método OnDeserialization solo se llamará una vez que se haya deserializado el gráfico de objetos entero, incluido el objeto classB.

Cuestiones relacionadas