protobuf-net中序列化回调和AddSubtype的问题

时间:2011-06-20 05:28:41

标签: .net protobuf-net

  public class A
  {
    public int X { get; private set; }
    public A(int x)
    {
      X = x;
    }

    public static implicit operator ASurrogate(A a)
    {
      return a == null ? null : new ASurrogate { X = a.X };
    }
    public static implicit operator A(ASurrogate a)
    {
      return a == null ? null : new A(a.X);
    }
  }

  [ProtoContract]
  public abstract class ASurrogateBase
  {
    public abstract int X { get; set; } 
  }

  [ProtoContract]
  public class ASurrogate : ASurrogateBase
  {
    [OnSerializing]
    public void OnSerializing(StreamingContext context)
    {
      X = 17;
    }

    [OnDeserialized]
    public void OnDeserialized(StreamingContext context)
    {
      X = 117;
    }

    [ProtoMember(1)]
    public override int X { get; set; }
  }

  [ProtoContract]
  public class B
  {
    [ProtoMember(1)]
    public A A { get; set; }
  }

  class Program
  {
    static void Main()
    {
      var m = RuntimeTypeModel.Default;
      m.AutoCompile = false;
      m.Add(typeof(ASurrogateBase), true).AddSubType(1, typeof(ASurrogate)); // (*)
      m.Add(typeof(A), false).SetSurrogate(typeof(ASurrogate));

      var b = new B { A = new A(117) };
      using (var ms = new MemoryStream())
      {
        Serializer.Serialize(ms, b);
        ms.Position = 0;
        var b2 = Serializer.Deserialize<B>(ms);
        Debug.Assert(b.A.X == b2.A.X);
      }
    }
  }

此程序的问题是既没有调用序列化回调。但是,如果删除语句(*),则一切正常。

是否按设计?

1 个答案:

答案 0 :(得分:1)

  

是否按设计?

不,不是。简短的版本是它没有考虑代理的继承,并且(由于各种原因)大多数回调仅由继承链的有效基类型调用(这里的例外是OnDeserializing,它在子类型中调用创建对象时的级别。)

这已在r414中修复