Я создаю прототип Protobuf-net, чтобы заменить часть нашего существующего кода C #, который в настоящее время использует [Datacontract] для сериализации объектов в Xml.
Используя protobuffer, мы можем легко обмениваться данными с Java. Таким образом, я очень заинтересован в генерации файла .proto Protobuf-net. Это работало хорошо почти во всех случаях использования, которые я тестировал до сих пор.
Но теперь с наследованием это другая игра с мячом. Файл .proto, который был сгенерирован для наследуемых классов, очень прост - не включая поля для базового класса.
Само наследование работает нормально в C # - я могу прочитать сгенерированный поток байтов (см. Мой тест ниже). Таким образом, внутренний двоичный поток содержит все поля базового класса
Сгенерированный .proto:
message ProtoScholar {
optional string Subject = 1;
}
Если я могу понять, как записывается поток байтов, я могу вручную создать соответствующий файл .proto.
Кто-нибудь имел опыт создания файла .proto для наследования с использованием protobuf-net?
Любая информация о том, как создается поток данных для наследования, будет отличной.
Моя модель данных выглядит следующим образом:
[DataContract]
[ProtoInclude(7, typeof(ProtoScholar))]
public class ProtoAlien
{
[DataMember(Order = 1)]
public string Name
{
get;
set;
}
[DataMember(Order = 2)]
public double? Average
{
get;
set;
}
[DataMember(Order = 3)]
public int? HowMuch
{
get;
set;
}
[DataMember(Order = 4, IsRequired = true)]
public Height Length
{
get; set;
}
[DataMember(Order = 5, IsRequired = true)]
public Character Personality
{
get;
set;
}
[DataMember(Order = 6, IsRequired = true)]
public DateTime When
{
get; set;
}
public enum Height
{
Short = 1,
Medium,
Tall
}
public enum Character : long
{
Wasp = 1717986918,
BumbleBee,
WorkerBee,
Hornet,
Queen
}
}
[DataContract()]
public class ProtoScholar : ProtoAlien
{
[DataMember(Order=1)]
public string Subject
{
get; set;
}
}
Мой тест NUnit выглядит так:
[Test]
public void TestInheritanceSupport()
{
var protoBuffer = new ProtoScholar
{
Name = "Ben11",
HowMuch = null,
Length = ProtoAlien.Height.Tall,
Personality = ProtoAlien.Character.WorkerBee,
When = new DateTime(2010, 4, 1, 2, 33, 56, 392),
Subject = "Alien Economics"
};
using (var ms = new MemoryStream())
{
var proto = Serializer.GetProto<ProtoScholar>();
Console.WriteLine(proto);
//Serialize to a Memory Stream
Serializer.Serialize(ms, protoBuffer);
Console.WriteLine(ms.Length);
ms.Position = 0;
var deserializedProtoBuffer = Serializer.Deserialize<ProtoScholar>(ms);
Assert.AreEqual("Ben11", deserializedProtoBuffer.Name);
Assert.Null(deserializedProtoBuffer.HowMuch);
Assert.AreEqual(ProtoAlien.Height.Tall, deserializedProtoBuffer.Length);
Assert.AreEqual(ProtoAlien.Character.WorkerBee, deserializedProtoBuffer.Personality);
Assert.AreEqual(new DateTime(2010, 4, 1, 2, 33, 56, 392), deserializedProtoBuffer.When);
Assert.AreEqual("Alien Economics", deserializedProtoBuffer.Subject);
}
}