问题
I am sorry if this is a duplicate. I have searched several places for an answer that I might understand including:
ProtoBuf.net Base class properties is not included when serializing derived class
Serialize inherited classes using protobuf-net
My apologies but I did not really understand the answers. I am looking for a faster more compact binary serializer and ProtoBuf looks like it might be the answer. I need to serialize a set of classes that all derive from a single base class. There are a large number of them so before committing to edit the class code I ran a simple test. Also I do not want to modify the classes in any way that might impact deserializing older persisted files generated with the NET binary serializer.
This is the base class:
[ProtoContract]
public class BaseClass
{
[ProtoMember(1)]
public string Name
{
get; set;
}
[ProtoMember(2)]
public int Age
{
get; set;
}
}
This is the derived class:
[ProtoContract]
public class SubClass1 : BaseClass
{
[ProtoMember(3)]
public string Town
{
get; set;
}
[ProtoMember(4)]
public Sex Sex
{
get; set;
}
}
This is the code to serialize and deserialize (taken directly from the Getting Started Guide
var person = new SubClass1 { Age = 25, Name = "Fred", Town = "Denbigh", Sex = Sex.Female };
using (var file = File.Create(filename))
{
Serializer.Serialize(file, person);
}
and 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);
The result is " : Denbigh : 0 : Female"
Somehow the values from the base class properties are not being serialized? I originally tested it with the ProtoMember indices for the derived class as 1, 2. I kind of thought that would not work so went for 3, 4. It seems to make no difference. In my paranoia I ran the same test using the standard NET binary serializer and got the expected result: "Fred : Denbigh : 25 : Female"
What am I missing please?
回答1:
You need to use the ProtoInclude
attribute on your base class:
[ProtoContract]
[ProtoInclude(500, typeof(SubClass1 ))]
public class BaseClass
{
The id arg (500 in the above example) should be unique to that class. See this article for more information
回答2:
I know it's quite old, but may help somebody. In some cases you can fix this by redefining base properties in your subtype:
[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;
}
}
来源:https://stackoverflow.com/questions/12988964/how-to-serialize-inherited-class-with-protobuf-net