I have an abstract base class that has an abstract byte[] Data property. My
goal is to have derived classes that contain arrays of structs, and to manually
serialize those structs to byte[] and back in the get/set of the Data property.
On the base class I have ProtoContract and ProtoInclude attributes, the issue
is that it includes the Data[] property twice in the message instead of once as
expected.
As a workaround I can get it to work as expected if I put a ProtoIgnore
attribute on the derived class Data property. Am I setting something up
incorrectly? I couldn't find any examples of inheritance in the code base that
have an abstract property defined on the base class and it implemented in the
derived class.
==============
What steps will reproduce the problem?
1. Run the included sample code
What is the expected output? What do you see instead?
Without the ProtoIgnore on the derived types properties they get included in
the message twice:
ProtoPackageA get Data
ProtoPackageA get Data
ProtoPackageB get Data
ProtoPackageB get Data
Serialized size: 1050
ProtoPackageA set Data
ProtoPackageA set Data
ProtoPackageB set Data
ProtoPackageB set Data
ProtoPackageA: 1
ProtoPackageB: 2.5
Done
With the ignore attribute it behaves as expected:
With the ignore message it behaves as expected:
ProtoPackageA get Data
ProtoPackageB get Data
Serialized size: 530
ProtoPackageA set Data
ProtoPackageB set Data
ProtoPackageA: 1
ProtoPackageB: 2.5
Done
What version of the product are you using? On what operating system?
282
Please provide any additional information below.
IProtoPackage[] packageArray = new IProtoPackage[] { new ProtoPackageA(1), new
ProtoPackageB(2.5m) };
MemoryStream stream = new MemoryStream();
Serializer.SerializeWithLengthPrefix<IProtoPackage[]>(stream, packageArray,
PrefixStyle.Base128);
stream.Flush();
Console.WriteLine("Serialized size: " + stream.Position);
stream.Seek(0, SeekOrigin.Begin);
IProtoPackage[] deserArray =
Serializer.DeserializeWithLengthPrefix<IProtoPackage[]>(stream,
PrefixStyle.Base128);
foreach (IProtoPackage package in deserArray)
{
Console.WriteLine(package.ToString());
}
[DataContract, ProtoContract]
[KnownType(typeof(ProtoPackageA)), ProtoInclude(1, typeof(ProtoPackageA))]
[KnownType(typeof(ProtoPackageB)), ProtoInclude(2, typeof(ProtoPackageB))]
abstract class IProtoPackage
{
[DataMember, ProtoMember(3)]
public abstract byte[] Data { get; set; }
}
[DataContract, ProtoContract]
class ProtoPackageA : IProtoPackage
{
private int _identifier;
private ProtoPackageA() { }
public ProtoPackageA(int id)
{
_identifier = id;
}
//[ProtoIgnore]
public override byte[] Data
{
get
{
Console.WriteLine("ProtoPackageA get Data");
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(_identifier);
return stream.GetBuffer();
}
set
{
Console.WriteLine("ProtoPackageA set Data");
MemoryStream inputStream = new MemoryStream(value);
using (BinaryReader reader = new BinaryReader(inputStream))
_identifier = reader.ReadInt32();
}
}
public override string ToString()
{
return string.Format("ProtoPackageA: {0}", _identifier);
}
}
[DataContract, ProtoContract]
class ProtoPackageB : IProtoPackage
{
private decimal _identifier;
private ProtoPackageB() { }
public ProtoPackageB(decimal id)
{
_identifier = id;
}
//[ProtoIgnore]
public override byte[] Data
{
get
{
Console.WriteLine("ProtoPackageB get Data");
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(_identifier);
return stream.GetBuffer();
}
set
{
Console.WriteLine("ProtoPackageB set Data");
MemoryStream inputStream = new MemoryStream(value);
using (BinaryReader reader = new BinaryReader(inputStream))
_identifier = reader.ReadDecimal();
}
}
public override string ToString()
{
return string.Format("ProtoPackageB: {0}", _identifier);
}
}
Original issue reported on code.google.com by Brandon...@gmail.com on 29 Sep 2010 at 4:33
Original issue reported on code.google.com by
Brandon...@gmail.com
on 29 Sep 2010 at 4:33