2009-06-02 21 views
6

Tengo datos almacenados en una instancia de una clase que se ha serializado con el .NET BinaryFormatter. Ahora quiero cambiar el nombre de uno de los campos de la clase, pero aún así poder deserializar los datos anteriores.Renombrar campos y luego deserializar en C#

Una opción es implementar ISerializable y deserializar todos los campos de la clase manualmente. Pero esto parece mucho trabajo, especialmente si mi clase tiene muchos campos y solo he cambiado el nombre de un solo campo.

¿Hay una manera mejor?


Craig sugiere mantener una copia de la clase de edad de deserialización, y los valores de copia a la nueva clase. He visto esto sugerido en otros lugares también: ¿qué ventaja tiene esto sobre la implementación de ISerializable? Por lo que puedo ver, copiar la clase me deja con 2 copias casi idénticas de la clase y aún tengo que copiar todos los valores de la clase anterior a la nueva clase, lo que parece ser la misma cantidad de trabajo que implementar ISerializable con una clase. casi duplicar la clase lanzada en la mezcla.


Dos respuestas han mencionado Binders. He utilizado con éxito un SerializationBinder para deserializar una clase Bar que estaba serializada como clase Foo, pero eso se debe a que el nombre de la clase ha cambiado. ¿SerializationBinder también ayuda cuando ha cambiado el nombre de un campo, por ejemplo, cuando int m_Left ha cambiado de nombre a int m_Right?

+0

En el método BindToType en Binder, cuando obtiene typeName cadena con tipo de destino (clase), simplemente devuelva el nuevo tipo donde cambió su propiedad. La clase solo ha cambiado propiedades, pero ahora es diferente. No hay forma de aplicar solo a una propiedad. –

Respuesta

2

Puedes intentar que el viejo calss se quede con el único propósito de la rehidratación y luego simplemente copiar los campos que necesitas a la nueva clase. Todavía es un poco doloroso, pero debería funcionar.

1

Sí, este es el problema con los serializadores basados ​​en el campo. Puede usar un Binder personalizado o un "sustituto de serialización" para evitar la implementación de ISerializable, pero eso es solo una solución caso por caso.

He discutido este tema (en el contexto de ofuscadores y autopropulsados) here. Mi consejo es: no utilice BinaryFormatter para la persistencia de datos entre versiones ... para que, mira serializadores basados ​​en contratos:

  • XmlSerializer
  • DataContractSerializer
  • o binaria, cosas como protobuf-net

Nada de esto le ayuda hoy, pero podría ayudarlo a diseñarlo en el futuro.

0

¿Qué pasa si simplemente cambia el modificador de acceso en esa propiedad a privado, y luego tiene una propiedad pública con el nuevo nombre que básicamente envuelve la anterior. De esa manera, todavía deberías poder deserializar (PIENSO) pero cualquiera que use esta clase no sabrá sobre el nombre anterior. Solo un pensamiento...

+0

Eso funcionaría si la serialización estuviera actuando sobre propiedades, pero hasta donde puedo decir, está trabajando directamente con los campos privados de todos modos ... (si abro el archivo en el bloc de notas, veo nombres de campos como m_Foo y m_Bar, en su lugar de nombres de propiedades como Foo y Bar ... –