序列化派生类时不包括 ProtoBuf.net 基类属性

Posted

技术标签:

【中文标题】序列化派生类时不包括 ProtoBuf.net 基类属性【英文标题】:ProtoBuf.net Base class properties is not included when serializing derived class 【发布时间】:2011-05-24 11:45:06 【问题描述】:

使用 ProtoBuf.net 的最新 2.0 beta 版本,我正在尝试序列化派生类(只是示例),但我得到了空文件。为什么基类属性没有序列化?

[ProtoContract]
[Serializable]
public class Web2PdfClient : Web2PdfEntity




[ProtoContract]
[Serializable]
public class Web2PdfEntity : EngineEntity


    [ProtoMember(1)]
    public string Title  get; set; 
    [ProtoMember(2)]
    public string CUrl  get; set; 
    [ProtoMember(3)]
    public string FileName  get; set; 




[ProtoContract]
[Serializable]
public class EngineEntity


    public bool Result  get; set; 
    public string ErrorMessage  get; set; 
    public bool IsMembershipActive  get; set; 
    public int ConversionTimeout  get; set; 
    public byte[] FileStorage  get; set; 

使用下面的代码序列化类时,我得到一个空文件。

var Web2PDF = new Web2PdfClient
                                                          
                              CUrl = "http://www.google.com",
                              FileName = "test.txt"
                          ;
        using (var file = File.Create(@"C:\Users\Administrator\Projects\temp\test.bin"))
        
            Serializer.Serialize(file, Web2PDF);

        

【问题讨论】:

【参考方案1】:

实际上,我很惊讶没有抛出异常——我会调查的!为了使它起作用,基本类型必须有一种独特的方式来指示每个子类型。这可以通过属性指定,或者(在 v2 中)在运行时指定。例如:

[ProtoContract]
[Serializable]
public class Web2PdfClient : Web2PdfEntity




[ProtoContract]
[ProtoInclude(7, typeof(Web2PdfClient))]
[Serializable]
public class Web2PdfEntity : EngineEntity
 ... 

7 没有什么特别之处,只是它不应该与为该类型定义的任何其他成员发生冲突。可以定义多个子类型(使用不同的标签)。另请注意,protobuf-net 不查看 [Serializable],因此您不需要它,除非您还使用 BinaryFormatter(或类似的)。

同样,EngineEntity 应该宣传 预期的子类型,并且应该指出要序列化的成员(以及针对哪个标签)。

【讨论】:

马克,我还有其他问题,希望可以使用评论提问,因为它与这个问题有关。您说基类必须标有指示继承类的属性。如果 Base 类位于单独的类库中怎么办?我不能将 [ProtoInclude(7, typeof(MyInheritedClass))] 放在基类上,因为我会收到 MyInheritedClass 未解决的错误。 @Tomas - 如果基本类型不知道派生类型,那么您也可以在 v2 的运行时使用 TypeModel 和 AddSubType 对其进行配置;即typeModel.Add(typeof(Web2PdfEntity), false).AddSubType(7, typeof(Web2PdfClient)); 并使用typeModel.Serialize 等(缓存并重用模型,因为它涉及生成的IL 等)

以上是关于序列化派生类时不包括 ProtoBuf.net 基类属性的主要内容,如果未能解决你的问题,请参考以下文章

定义派生类时,为啥基类标记为“public”? [复制]

仅在 ProtoBuf-net 中序列化基类

当有多个派生类时,如何使用基类指针访问派生类的函数成员?

在不同的命名空间中定义基类和派生类时的编译错误

在 C++ 继承中,当指向基类的指针对象指向派生类时,不调用派生类析构函数

当我在 C++ 中派生一个类时,它是不是会创建一个基类对象并将其作为我的成员变量存储在派生类中?