C# 如何用ProtoBuf-Net序列化继承的类

C# 如何用ProtoBuf-Net序列化继承的类,c#,serialization,protobuf-net,C#,Serialization,Protobuf Net,如果这是重复的,我很抱歉。我在几个地方搜索了一个我可能理解的答案,包括: 我很抱歉,但我并没有真正理解答案。我正在寻找一个更快更紧凑的二进制序列化程序,ProtoBuf看起来可能就是答案。我需要序列化一组从单个基类派生的类。它们有很多,所以在提交编辑类代码之前,我运行了一个简单的测试。此外,我不想以任何方式修改类,这可能会影响使用NET二进制序列化程序生成的旧的持久化文件的反序列化 这是基类: [ProtoContract] public class BaseClass {

如果这是重复的,我很抱歉。我在几个地方搜索了一个我可能理解的答案,包括:

我很抱歉,但我并没有真正理解答案。我正在寻找一个更快更紧凑的二进制序列化程序,ProtoBuf看起来可能就是答案。我需要序列化一组从单个基类派生的类。它们有很多,所以在提交编辑类代码之前,我运行了一个简单的测试。此外,我不想以任何方式修改类,这可能会影响使用NET二进制序列化程序生成的旧的持久化文件的反序列化

这是基类:

[ProtoContract]
    public class BaseClass
    {
        [ProtoMember(1)]
        public string Name
        {
            get; set;
        }
        [ProtoMember(2)]
        public int Age
        {
            get; set;
        }
    }
[ProtoContract]
[ProtoInclude(500, typeof(SubClass1 ))]
public class BaseClass
{
这是派生类:

[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);
            }
和反序列化:

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

            MessageBox.Show(newPerson.Name + 
                " : " + newPerson.Town + 
                " : " + newPerson.Age.ToString() + 
                " : " + newPerson.Sex);
第1子类newPerson;
使用(var file=file.OpenRead(文件名))
{
newPerson=序列化程序。反序列化(文件);
}
MessageBox.Show(newPerson.Name+
“:”+newPerson.Town+
“:”+newPerson.Age.ToString()+
“:”+newPerson.Sex);
结果是:“登比赫:0:女性”

不知怎的,基类属性中的值没有被序列化?我最初用派生类的ProtoMember索引1,2测试了它。我有点认为这不起作用,所以选择了3,4。这似乎没有什么区别。在我的妄想症中,我使用标准的NET二进制序列化程序运行了相同的测试,得到了预期的结果d结果:“弗雷德:邓比赫:25:女性”


请问我缺少什么?

您需要在基类上使用
ProtoInclude
属性:

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

id arg(在上面的示例中为500)对于该类来说应该是唯一的。有关详细信息,请参阅文章

我知道它很旧,但可能对某些人有所帮助。在某些情况下,您可以通过在子类型中重新定义基属性来解决此问题:

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

非常感谢,非常感谢simple@RenniePet这是我的网站,停止维护,时间不好!@wal 500 id arg对于子类或解决方案中的所有ProtoInclude属性都应该是唯一的?我相信它是第一个,但你让它听起来像是第二个。这个设计似乎是倒退的。如果我有一个基类在另一个库中,而这个库不存在呢(而且不应该)知道我的应用程序中的类吗?你能将标签号添加到子类中吗?@rushonerok我还应该注意:使用protobuf net的v2,你可以动态构建一个序列化程序,这意味着你不必用属性装饰类。参见我的文章我在应用程序中使用此方法来处理你描述的情况-这就是我定义的知道(引用)我的应用程序中所有需要序列化的类的序列化模型-这意味着您的基类可以不知道任何子类,仍然可以序列化!我认为这不会起作用,因为
子类1
将有两个属性定义为
ProtoMember
,索引为1(
Name
BaseName