c# - Cómo serializar una clase heredada con ProtoBuf-Net
serialization (2)
Lo siento si esto es un duplicado. He buscado en varios lugares una respuesta que pueda comprender, incluyendo:
Las propiedades de clase base de ProtoBuf.net no se incluyen al serializar la clase derivada
Serializar clases heredadas usando protobuf-net
Mis disculpas pero realmente no entendí las respuestas. Estoy buscando un serializador binario más rápido y más compacto y parece que ProtoBuf podría ser la respuesta. Necesito serializar un conjunto de clases que derivan de una única clase base. Hay un gran número de ellos, por lo que antes de comprometerme a editar el código de clase realicé una prueba simple. Además, no quiero modificar las clases de ninguna manera que pueda afectar la deserialización de archivos antiguos persistentes generados con el serializador binario NET.
Esta es la clase base:
[ProtoContract]
public class BaseClass
{
[ProtoMember(1)]
public string Name
{
get; set;
}
[ProtoMember(2)]
public int Age
{
get; set;
}
}
Esta es la clase derivada:
[ProtoContract]
public class SubClass1 : BaseClass
{
[ProtoMember(3)]
public string Town
{
get; set;
}
[ProtoMember(4)]
public Sex Sex
{
get; set;
}
}
Este es el código para serializar y deserializar (tomado directamente de la Guía de Inicio)
var person = new SubClass1 { Age = 25, Name = "Fred", Town = "Denbigh", Sex = Sex.Female };
using (var file = File.Create(filename))
{
Serializer.Serialize(file, person);
}
y deserializar:
SubClass1 newPerson;
using (var file = File.OpenRead(filename))
{
newPerson = Serializer.Deserialize<SubClass1>(file);
}
MessageBox.Show(newPerson.Name +
" : " + newPerson.Town +
" : " + newPerson.Age.ToString() +
" : " + newPerson.Sex);
El resultado es ": Denbigh: 0: Female"
De alguna manera, ¿los valores de las propiedades de la clase base no se están serializando? Originalmente lo probé con los índices ProtoMember para la clase derivada como 1, 2. En cierto modo pensé que eso no funcionaría, así que fue por 3, 4. Parece que no importa. En mi paranoia ejecuté la misma prueba usando el serializador binario NET estándar y obtuve el resultado esperado: "Fred: Denbigh: 25: Female"
¿Qué me estoy perdiendo por favor?
Necesita usar el atributo ProtoInclude
en su clase base:
[ProtoContract]
[ProtoInclude(500, typeof(SubClass1 ))]
public class BaseClass
{
El ID ARG (500 en el ejemplo anterior) debe ser exclusivo de esa clase. Ver this artículo para más información
Sé que es bastante viejo, pero puede ayudar a alguien. En algunos casos, puede solucionar esto redefiniendo las propiedades base en su subtipo:
[ProtoContract]
public class SubClass1 : BaseClass
{
[ProtoMember(1)]
public string BaseName
{
get{return base.Name;}
set{base.Name = value;}
}
...
[ProtoMember(3)]
public string Town
{
get; set;
}
[ProtoMember(4)]
public Sex Sex
{
get; set;
}
}