由于上面的帖子已经关闭,我创建了一个新的帖子,其中包含用于重现问题和异常堆栈跟踪的测试代码。
这是怎么回事,为什么错误?我还不清楚ProtoInclude的标签。如果标签等于ProtoMember,那么我会得到一个关于重复字段编号的例外。所以,我通常将它设置为max(ProtoMember标签)+ 1.这是工具所期望的吗?
我使用svn的最新代码(今天下载)运行此示例。
由于
[ProtoContract]
[ProtoInclude(6, typeof(B))]
public class A
{
[ProtoMember(1)]
public int Property1 { get; set; }
[ProtoMember(2)]
public int? Property2 { get; set; }
[ProtoMember(3)]
public int Property3 { get; set; }
[ProtoMember(4, DynamicType = true)]
public object Property4 { get; set; }
[ProtoMember(5, DynamicType = true)]
public object Property5 { get; set; }
public override bool Equals(object obj)
{
A a = obj as A;
if (a == null)
return false;
return a.Property1 == this.Property1
&& a.Property2 == this.Property2
&& a.Property3 == this.Property3
&& Object.Equals(a.Property4, this.Property4)
&& Object.Equals(a.Property5, this.Property5);
}
}
public class B: A
{
[ProtoMember(1)]
public string Property6 { get; set; }
public override bool Equals(object obj)
{
B b = obj as B;
if (b == null)
return false;
return b.Property6 == this.Property6 && base.Equals(obj);
}
}
[Test]
public void TestProtoBuf2()
{
IList<A> list = new List<A>
{
new A {Property1 = 1, Property2 = 1, Property3 = 200, Property4 = "Test1", Property5 = DateTime.Now},
new B {Property1 = 2, Property2 = 2, Property3 = 400, Property4 = "Test2", Property5 = DateTime.Now, Property6 = "yyyy"},
new A {Property1 = 3, Property2 = 3, Property3 = 600, Property4 = "Test3", Property5 = new Decimal(200)},
};
using (var file = new FileStream("list.bin", FileMode.Create))
{
Serializer.Serialize(file, list);
}
IList<A> list2;
using (var file = File.OpenRead("list.bin"))
{
list2 = Serializer.Deserialize<IList<A>>(file);
}
Assert.AreEqual(list.Count, list2.Count);
for (int i = 0; i < list.Count; i++)
{
Assert.AreEqual(list[i], list2[i]);
}
}
堆栈追踪:
at ProtoBuf.BclHelpers.ReadNetObject(Object value, ProtoReader source, Int32 key, Type type, NetObjectOptions options) in BclHelpers.cs: line 444
at ProtoBuf.Serializers.NetObjectSerializer.Read(Object value, ProtoReader source) in C:\Development\dotnet\protobuf-net\protobuf-net\Serializers\NetObjectSerializer.cs: line 37
at ProtoBuf.Serializers.TagDecorator.Read(Object value, ProtoReader source) in C:\Development\dotnet\protobuf-net\protobuf-net\Serializers\TagDecorator.cs: line 61
at ProtoBuf.Serializers.PropertyDecorator.Read(Object value, ProtoReader source) in C:\Development\dotnet\protobuf-net\protobuf-net\Serializers\PropertyDecorator.cs: line 53
at ProtoBuf.Serializers.TypeSerializer.Read(Object value, ProtoReader source) in TypeSerializer.cs: line 200
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) in C:\Development\dotnet\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs: line 418
at ProtoBuf.Meta.TypeModel.TryDeserializeAuxiliaryType(ProtoReader reader, DataFormat format, Int32 tag, Type type, ref Object value, Boolean skipOtherFields, Boolean asListItem, Boolean autoCreate, Boolean insideList) in C:\Development\dotnet\protobuf-net\protobuf-net\Meta\TypeModel.cs: line 895
at ProtoBuf.Meta.TypeModel.TryDeserializeList(ProtoReader reader, DataFormat format, Int32 tag, Type listType, Type itemType, ref Object value) in C:\Development\dotnet\protobuf-net\protobuf-net\Meta\TypeModel.cs: line 712
at ProtoBuf.Meta.TypeModel.TryDeserializeAuxiliaryType(ProtoReader reader, DataFormat format, Int32 tag, Type type, ref Object value, Boolean skipOtherFields, Boolean asListItem, Boolean autoCreate, Boolean insideList) in C:\Development\dotnet\protobuf-net\protobuf-net\Meta\TypeModel.cs: line 851
at ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoReader reader, Type type, Object value, Boolean noAutoCreate) in C:\Development\dotnet\protobuf-net\protobuf-net\Meta\TypeModel.cs: line 594
at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context) in C:\Development\dotnet\protobuf-net\protobuf-net\Meta\TypeModel.cs: line 518
at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type) in C:\Development\dotnet\protobuf-net\protobuf-net\Meta\TypeModel.cs: line 500
at ProtoBuf.Serializer.Deserialize(Stream source) in C:\Development\dotnet\protobuf-net\protobuf-net\Serializer.cs: line 69
答案 0 :(得分:0)
重新输入字段编号;它们需要在一种类型中独一无二;它不是必需它是“max + 1” - 它们不必是连续的 - 但是,小数字是优选的(只要它们是正数),因为“varint”编码可以更有效地打包低字段数字(用于标题)。
重新参考跟踪问题;这是一个错误,并在当前主干中修复 - 谢谢;边缘情况,但固定。