是否可以将具有属性的聚合类型反序列化为作为引用的抽象基类型,请参阅Aggregate.Base?如果没有,最好的解决方法是什么?
[ProtoContract]
[ProtoInclude(1, typeof(Derived))]
public abstract class Base { }
[ProtoContract]
public class Derived : Base
{
[ProtoMember(1)]
public int SomeProperty { get; set; }
}
[ProtoContract]
public class Aggregate
{
[ProtoMember(1, AsReference = true)]
public Base Base { get; set; }
}
[TestClass]
public class UnitTest
{
[TestMethod]
public void TestMethod1()
{
var value = new Aggregate { Base = new Derived() };
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, value);
stream.Position = 0;
// Raises an exception
// Unable to create type Sage.Estimating.Data.Base: Cannot create an abstract class.
Serializer.Deserialize<Aggregate>(stream);
}
}
}
在引发异常时调用堆栈:
protobuf-net.dll!ProtoBuf.BclHelpers.ReadNetObject(对象值,ProtoBuf.ProtoReader源,int键,System.Type类型,ProtoBuf.BclHelpers.NetObjectOptions选项)第428行+ 0xda字节C# protobuf-net.dll!ProtoBuf.Serializers.NetObjectSerializer.Read(对象值,ProtoBuf.ProtoReader源)第45行+ 0x9f字节C# protobuf-net.dll!ProtoBuf.Serializers.TagDecorator.Read(对象值,ProtoBuf.ProtoReader源)第66行+ 0x18字节C# protobuf-net.dll!ProtoBuf.Serializers.PropertyDecorator.Read(对象值,ProtoBuf.ProtoReader源)第74行+ 0x18字节C# protobuf-net.dll!ProtoBuf.Serializers.TypeSerializer.Read(对象值,ProtoBuf.ProtoReader源)第205行+ 0xf字节C# protobuf-net.dll!ProtoBuf.Meta.RuntimeTypeModel.Deserialize(int key,object value,ProtoBuf.ProtoReader source)Line 562 + 0xf bytes C# protobuf-net.dll!ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoBuf.ProtoReader reader,System.Type type,object value,bool noAutoCreate)634行+ 0x14字节C# protobuf-net.dll!ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream source,object value,System.Type type,ProtoBuf.SerializationContext context)Line 555 + 0x14 bytes C# protobuf-net.dll!ProtoBuf.Meta.TypeModel.Deserialize(System.IO.Stream source,object value,System.Type type)Line 534 + 0x13 bytes C# protobuf-net.dll!ProtoBuf.Serializer.Deserialize(System.IO.Stream source)第78行+ 0x5a字节C#
答案 0 :(得分:2)
感谢您的出色表现;不知道我怎么忽略了这一点。基本上,它归结为密钥跟踪,这在循环图中变得特别复杂。为了尽快获得密钥注册,使用做的是(对于新对象):
显然,在继承的情况下,第一步是错误,无论是否基本类型是抽象/不可创建的。它现在做的是:
null
这样做的结果是:它现在有效;您的测试通过,对象的类型正确:
var obj = Serializer.Deserialize<Aggregate>(stream);
Assert.AreEqual(typeof(Derived), obj.Base.GetType());
需要修订版556或更高版本。