【发布时间】:2016-11-11 23:15:16
【问题描述】:
protobuf-net.2.1.0
我的理解是,protobuf-net 完全根据接收方可用的信息来确定反序列化的消息合约——序列化数据包本身并不依赖于构造消息合约。具体来说,类成员属性表示数据类型和期望在数据包中找到的字段的顺序。
因此,由于发送方独立于接收方,如果字段数据和顺序与接收方原型合同定义的匹配,则应该可以将任何序列化数据包解释为某种类型。
特别是关于继承,应该可以序列化基类型的对象并反序列化为子类型的对象——前提是继承被正确标记。
但是,对于简单的继承层次结构DerivedClass : BaseClass,我发现如果我序列化为BaseClass 并反序列化为DerivedClass,返回的对象将是BaseClass 类型。
以下是课程:
[ProtoBuf.ProtoInclude(1000, typeof(DerivedClass))]
[ProtoBuf.ProtoContract]
public class BaseClass
{
[ProtoBuf.ProtoMember(1, IsRequired = false, Name = @"Name", DataFormat = ProtoBuf.DataFormat.TwosComplement)]
public string Name { get; set; }
}
[ProtoBuf.ProtoContract]
public class DerivedClass : BaseClass
{
[ProtoBuf.ProtoMember(2, IsRequired = false, Name = @"Index", DataFormat = ProtoBuf.DataFormat.TwosComplement)]
public int Index { get; set; }
}
执行以下测试方法:
public class TestClass
{
public static void Test()
{
var baseObject = new BaseClass { Name = "BaseObject" };
var derivedObject = new DerivedClass { Name = "DerivedObject", Index = 1 };
using (var stream = new MemoryStream())
{
ProtoBuf.Serializer.Serialize(stream, baseObject);
Debug.WriteLine(stream.Length);
stream.Seek(0, SeekOrigin.Begin);
// either of next two lines will throw the invalid cast exception :
// DerivedClass derivedObjectOut = ProtoBuf.Serializer.Deserialize<DerivedClass>(stream);
// var objectOut = ProtoBuf.Serializer.Deserialize<DerivedClass>(stream);
// no exception thrown but internal type of objectOut is unexpectedly BaseClass :
var objectOut = ProtoBuf.Serializer.Deserialize<DerivedClass>(stream);
}
}
}
产生异常:
“System.InvalidCastException”类型的异常发生在 protobuf-net.dll 但未在用户代码中处理
附加信息:无法转换类型的对象 'protobuf_net.lib.ProtoClasses.SimpleBaseClass' 键入 'protobuf_net.lib.ProtoClasses.SimpleDerivedClass'。
【问题讨论】:
-
@dbc 感谢您发现这些错别字(从错误的来源复制/粘贴)——我已经编辑了我的帖子,因此代码与描述相符
标签: c# inheritance serialization deserialization protobuf-net