2013-08-19 63 views
3

我使用protobuf-net 2.0.0.640版來序列化一些數據,如下所示。定義繼承後的Protobuf-net反序列化

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)] 
public interface ITestMessage 
{ 

} 

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)] 
public class MyOrder : ITestMessage 
{ 
    public int Amount { get; set; } 
} 

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)] 
public class MyOrderWrapper 
{ 
    public MyOrder Order { get; set; } 
} 

[TestMethod] 
public void TestOrderSerialize() 
{ 
    var order = new MyOrder() {Amount = 10}; 
    var orderWrapper = new MyOrderWrapper() { Order = order }; 

    using (var file = File.Create("C:\\temp\\order.bin")) 
    { 
     Serializer.Serialize<MyOrderWrapper>(file, orderWrapper); 
    } 
} 

現在,如果我宣佈通過代碼「ITestMessage」 &「MyOrder」使用之間的繼承依賴關係:

RuntimeTypeModel.Default[typeof(ITestMessage)].AddSubType(2, typeof(MyOrder)); 

嘗試反序列化時,我得到了下面的錯誤我prevously保存的數據。 「沒有爲ITestMessage找到無參數的構造函數」。

[TestMethod] 
public void TestOrderDeserialize() 
{ 
    RuntimeTypeModel.Default[typeof(ITestMessage)].AddSubType(2, typeof(MyOrder)); 

    MyOrderWrapper orderWrapper; 
    using (var file = File.OpenRead("C:\\temp\\order.bin")) 
    { 
     orderWrapper = Serializer.Deserialize<MyOrderWrapper>(file); 
    } 
} 

是否有人可以解釋爲什麼當「MyOrderWrapper」不引用任何東西比在繼承hirarchy「MyOrder」高會發生這種事。

另外,爲什麼它的工作原理,當我顯式地包括在 'ITestMessage'

由於

回答

1

基本上 '[ProtoInclude(2的typeof(MyOrder))]',這是一個重大更改只要序列化器 - 關於線層,既不存在「類」也不存在「接口」,因此就存儲而言,這類似於改變類的基類型;在序列化時,根類型爲MyOrder - 在反序列化期間,根類型爲ITestMessage。這不會讓它開心。

基本上:你不能那樣做。

+0

爲什麼它會顯式定義屬性?此外,有關如何解決此問題的任何建議?即重新讀取以前的數據,然後構建一個新模型以包含關係。 – Prin

+0

@Prin你的意思是「另外,爲什麼它的工作,當我明確包括'[ProtoInclude(2,typeof(MyOrder))]'''ITestMessage'」 - 嗯;我必須看一看,但我懷疑*這實際上並不是模型的一部分;它會自動檢測基本類型的契約,但我認爲它並不走向接口,因爲它們在重要的方面有很大不同 –