6

Tengo una clase C# que se serializa en disco por los BinaryFormatter, como este ejemplo:Cómo refactorizar una clase que se serializa en .NET?

// Version 3.0 
[Serializable] 
public class Person 
{ 
    public string FullName; 

    [OptionalField(VersionAdded=2)] 
    public string NickName; 
    [OptionalField(VersionAdded=2)] 
    public DateTime BirthDate; 

    [OptionalField(VersionAdded=3)] 
    public int Weight; 
} 

Más tarde, quiero refactorizar esta clase por uno o más de los siguientes
- Cambie su nombre
- Cambie su espacio de nombres
- Mover a otra asamblea

Por lo que yo puedo decir, el archivo binario sólo puede ser serializado-dE, siempre una clase con el mismo nombre, espacio de nombres y montaje nombre exacto está disponible.

¿Cómo puedo solucionar esto?
¿Es posible asignar la deserialización a un nombre de clase, espacio de nombres y ensamblaje diferente sin romper Version Tolerant Serialization?

Respuesta

5

Después de algunas investigaciones me di cuenta de que BinaryFormatter es compatible con todo lo que estaba buscando.

Un BinaryFormatter puede utilizar sustitutos a

  1. proporciona la capacidad para serializar un tipo que no fue diseñado originalmente para ser serializado.
  2. Proporciona una forma de asignar una versión de un tipo a otra versión de otro tipo.

Uno puede también asignar deserialización de tipo A al tipo B (diferente nombre de clase, espacio de nombres y/o nombre de ensamblado) utilizando SerializationBinder.

Por lo que puedo decir, esto permite refactorizar las clases que se serializan y mantener la compatibilidad con versiones anteriores al realizar cambios de interrupción que no son compatibles solo con el control de versiones.

Referencia: http://www.diranieh.com/NETSerialization/BinarySerialization.htm

Editar: En una nota lateral, los campos de refactorización (nombre o tipo) sigue siendo un dolor, como se discute en Renaming fields then deserializing in C#. Actualmente estoy buscando en protobuf-net para resolver mejor esto en el futuro.

1

Puede implementar la interfaz ISerializable y anular GetObjectData para proporcionar su propia deserialización. No lo he intentado, pero deberías poder deserializar tu objeto viejo "manualmente".

+0

¿Quiere decir que Person debería implementar ISerializable y GetObjectData()? ¿Cómo sabrá el deserializador que se debe usar esta clase de Persona exacta, cuando tiene un nombre, un espacio de nombres y/o un ensamblaje diferente? ¿De alguna manera puedo decirle al deserializador qué clase usar? – angularsen

Cuestiones relacionadas