首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取“A reference-tracked changed during deserialization”异常

获取“A reference-tracked changed during deserialization”异常
EN

Stack Overflow用户
提问于 2012-02-29 08:26:49
回答 1查看 547关注 0票数 1

这个问题与这个问题相关:https://stackoverflow.com/questions/7906356/how-to-solve-a-a-reference-tracked-object-changed-reference-during-deserializat

由于上面的帖子已经关闭,我创建了一个新的帖子,其中包括用于重现问题的测试代码和异常堆栈跟踪。

这里发生了什么,为什么会出现错误?另外,我也不清楚ProtoInclude的标签。如果标记等于一个ProtoMember,那么我会得到一个关于重复字段号的异常。所以,我通常将其设置为max(ProtoMember标签)+ 1。这是工具所期望的吗?

我使用来自svn的最新代码运行此示例(今天下载)。

谢谢

代码语言:javascript
复制
[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]);
  }
}

堆栈跟踪:

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-01 06:30:58

Re字段编号;它们在单个类型中必须是唯一的;不要求它是"max + 1“-它们不一定是连续的-但是,最好是小数字(只要它们是正数),因为"varint”编码可以更有效地打包较小的字段编号(用于标题)。

Re引用跟踪问题;这是一个bug,已在当前主干中修复-谢谢;边缘情况,但已修复。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9491933

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档