1

I have two classes A and B. Class B inherits class A as shown below.

<ProtoContract()>
Public Class A
    <ProtoMember(1)>
    Public Property ID As Integer
    <ProtoMember(2)>
    Public Property Name() As String = String.Empty
End Class

<ProtoContract()>
Public Class B
    Inherits A
    <ProtoMember(101)>
    Property Title As String = String.Empty
    <ProtoMember(102)>
    Property Status As String = String.Empty
    <ProtoMember(103)>
End Class

When I use ProtoBuf to serialize and deserialize an instance of class B, the class A property values are lost. After searching for a bit on this, I think I need to use the ProtoInclude() tag on Class B somehow but I have had little luck with it.

Example Code:

 Dim stuff as New B
 With stuff
   .ID = 1
   .Name = "Bob"
   .Title = "Director"
   .Status = "Active"
 End With

 Dim buffer as Byte()
 Dim deserializedStuff as new B

 Using memStream As New IO.MemoryStream
     ProtoBuf.Serializer.Serialize(memStream, stuff)
     buffer = memStream.ToArray
 End Using

 Using memStream As New MemoryStream(buffer)
     memStream.Position = 0  
     deserializedStuff = ProtoBuf.Serializer.Deserialize(Of B)(memStream)
 End Using

At this point, the inherited property values on "deserializedStuff" are lost. They appear to just be set to their default values. Any ideas on what I am doing wrong? Thanks in advance.

  • Cross referencing for later readers: this related **but different** question concerns where the *model* is inherited, but you don't want the wire-format to appear inherited: http://stackoverflow.com/questions/11947299/protobuf-net-inheritance-in-c-sharp-but-not-in-wire-format/11947837#11947837 – Marc Gravell Aug 15 '12 at 07:39

1 Answers1

2

In the ProtoAttributes for A, you need to specify that it can also contain B.

<ProtoContract(), ProtoInclude(100, GetType(B))>
Public Class A
    <ProtoMember(1)>
    Public Property ID As Integer
    <ProtoMember(2)>
    Public Property Name() As String = String.Empty
End Class

<ProtoContract()>
Public Class B
    Inherits A
    <ProtoMember(1)>
    Property Title As String = String.Empty
    <ProtoMember(2)>
    Property Status As String = String.Empty
End Class

And this is the test class I used to figure yours out.

Public Class Test
    Public Sub New()
        Dim stuff As New B With {.ID = 1, .Name = "Bob", .Title = "Director", 
             .Status = "Active"}

        Dim buffer As Byte()
        Using memStream As New IO.MemoryStream
            ProtoBuf.Serializer.Serialize(memStream, stuff)
            buffer = memStream.ToArray
        End Using

        Dim deserializedStuff As B
        Using memStream As New MemoryStream(buffer)
            memStream.Position = 0
            deserializedStuff = ProtoBuf.Serializer.Deserialize(Of B)(memStream)
        End Using

        Debug.Print(deserializedStuff.ID.ToString & "--" & deserializedStuff.Status)
    End Sub
End Class
Paul Farry
  • 4,730
  • 2
  • 35
  • 61