2011-11-11 67 views
4

this post中所述,我們可以使用ProtoInclude屬性來管理類層次結構序列化。如果我們只使用protobuf-net,它就可以在兩個方向上很好地工作。但是當我們嘗試反序列化消息時會出現問題,由「外部」傳統協議緩衝區實現序列化,例如。 Java等Protobuf-net中的繼承:ProtoInclude和兼容性

正如在上面的帖子中提到的,Protobuf-net通過「顛倒」的字節序列識別類層次結構,當父類的子類字段序列化之前。但遺留代碼按照「正確」順序將它們序列化,並且protobuf-net會拋出一個「無法投射類型'A'的對象以鍵入'B'。」反序列化中的異常。在相反的方向它工作正常,遺留代碼可以反序列化protobuf-net庫生成的「分層」消息。

我不能影響管道反面的字節序列化順序。我怎樣才能正確反序列化這種類型的消息在.NET protobuf網側?

更新:代碼示例

在我們行的結束,我們有原來的protobuf網層次類:

[ProtoContract, ProtoInclude(10, typeof(B))] 
public class A 
{ 
    [ProtoMember(1)] 
    public int Age; 
} 

public class B : A 
{ 
    [ProtoMember(2)] 
    public int Balls; 
} 

在班線的另一端使用.proto文件中生成:

message B { 
    optional int32 balls = 2; 
} 

message A { 
    optional int32 age = 1; 
    optional B b = 10; 
} 

生成的類的例子,我們可以使用protobuf-net生成器爲.NET創建它們:

[ProtoContract] 
public class A_generated 
{ 
    [ProtoMember(1)] 
    public int Age; 

    [ProtoMember(10)] 
    public B b; 
} 

[ProtoContract] 
public class B_generated 
{ 
    [ProtoMember(2)] 
    public int Balls; 
} 

所以,現在,讓我們序列化和反序列化類B:

  • 序列化和反序列化回原來類 - OK
  • 序列化和反序列化回產生類 - OK
  • 序列化原始並反序列化爲生成 - OK
  • 序列化產生和反序列化作爲原始 - 「無法轉換類型的對象 'A' 爲類型 'B'」 FAIL例外

我已經調查所得的字節,並發現了一個差異 - 字節順序

示例:讓Age = 10和Balls = 23。然後:

  • 原始乙序列化:[82,2,16,23,8,10],可使用既作爲原始作爲產生反序列化;
  • 生成 B序列化:[8,10,82,2,16,23],不能使用上面的protobuf-net 原始類進行反序列化。

我希望現在已經夠清楚了,並希望得到肯定的答案:是的,有一種方法可以使用ProtoInclude和反序列化泛型類。

+0

你可以在這裏更具體的情況?我的印象是,定期protobuf ***不包括***繼承。因此,它經常通過封裝來減薄。另外,您可以使用現有的.proto生成模型...?樂於幫助,但我想確保我的回答正確。 –

+0

啊,對。我現在瞭解上下文,謝謝。我明白髮生了什麼,爲什麼。我將在今天晚些時候進行調查,看看是否有簡單的解決方法。 –

+0

非常小,但是應該將A_generated.b鍵入爲B_generated?這並不能解決問題 - 我只是想在我的測試中做到精確... –

回答

1

編輯:這應該從r616開始支持v2。


要從protobuf/java tutorial引用:

不要去尋找類似的類繼承的設施,但 - 協議緩衝區不這樣做。

所以:無論你在本地使用本地欺騙繼承,我會建議:在這裏也使用它。例如,您可以通過protogen運行現有的.proto。

如果您可以對佈局非常具體(例如.proto示例),我可能會進一步提供建議。

+0

@亞歷克斯感謝修復;我一定是在移動或什麼的 –