Подтвердить что ты не робот

Как сериализовать унаследованный класс с ProtoBuf-Net

Прошу прощения, если это дубликат. Я искал несколько мест для ответа, который мог бы понять, включая:

Свойства базового класса ProtoBuf.net не включаются при сериализации производного класса

Сериализовать унаследованные классы, используя protobuf-net

Мои извинения, но я не очень понял ответы. Я ищу более быстрый компактный двоичный сериализатор, и ProtoBuf выглядит так, как будто это может быть ответ. Мне нужно сериализовать набор классов, которые все производятся из одного базового класса. Их очень много, поэтому, прежде чем совершать редактирование кода класса, я провел простой тест. Также я не хочу изменять классы каким-либо образом, которые могут повлиять на десериализацию старых файлов с сохранением, сгенерированных с помощью бинарного сериализатора NET.

Это базовый класс:

[ProtoContract]
    public class BaseClass
    {
        [ProtoMember(1)]
        public string Name
        {
            get; set;
        }
        [ProtoMember(2)]
        public int Age
        {
            get; set;
        }
    }

Это производный класс:

[ProtoContract]
    public class SubClass1 : BaseClass
    {
        [ProtoMember(3)]
        public string Town
        {
            get; set;
        }

        [ProtoMember(4)]
        public Sex Sex
        {
            get; set;
        }
    }

Это код для сериализации и десериализации (взятый непосредственно из руководства по началу работы

var person = new SubClass1 { Age = 25, Name = "Fred", Town = "Denbigh", Sex = Sex.Female };

            using (var file = File.Create(filename))
            {
                Serializer.Serialize(file, person);
            }

и de -serialize:

SubClass1 newPerson;
            using (var file = File.OpenRead(filename))
            {
                newPerson = Serializer.Deserialize<SubClass1>(file);
            }

            MessageBox.Show(newPerson.Name + 
                " : " + newPerson.Town + 
                " : " + newPerson.Age.ToString() + 
                " : " + newPerson.Sex);

Результат: "Denbigh: 0: Female"

Каким-то образом значения из свойств базового класса не сериализуются? Я первоначально тестировал его с индексами ProtoMember для производного класса как 1, 2. Я вроде бы думал, что это не сработает, так что пошел на 3, 4. Кажется, не имеет значения. В моей паранойе я провел один и тот же тест с использованием стандартного бинарного сериализатора NET и получил ожидаемый результат: "Fred: Denbigh: 25: Female"

Что я пропущу, пожалуйста?

4b9b3361

Ответ 1

Вам нужно использовать атрибут ProtoInclude в базовом классе:

[ProtoContract]
[ProtoInclude(500, typeof(SubClass1 ))]
public class BaseClass
{

Идентификатор arg (500 в приведенном выше примере) должен быть уникальным для этого класса. См. эту статью для получения дополнительной информации

Ответ 2

Я знаю, что он довольно старый, но может помочь кому-то. В некоторых случаях вы можете исправить это, переопределив базовые свойства в вашем подтипе:

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