2011-06-20 32 views
2
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); 
     } 
    } 
    } 

該程序的問題是,沒有序列化回調被調用。但是,如果我刪除了聲明(*),那麼一切正常。問題與序列化回調和AddSubtype在protobuf網

是否由設計?

回答

1

它是由設計嗎?

不,它不是。簡短的版本是它沒有考慮代理的繼承,並且(由於各種原因)大多數回調只能由繼承鏈的有效基類型調用(這裏的例外是OnDeserializing,它在子類型級別作爲對象創建)。

這固定在r414