2011-10-04 126 views
3

我試圖將真棒protobuf-net集成到現有的代碼庫中,但在嘗試處理自定義類型時遇到崩潰。一個小示例如下:它將在ProtoBuf.Serializers.ListDecorator中拋出InvalidOperationException。但是,如果您註釋掉索引器(或刪除IEnumerable實現),那麼它會乾淨地運行。protobuf-net如何避免在使用索引屬性時崩潰

using System.Collections.Generic; 
using ProtoBuf; 
using System.Collections; 

[ProtoContract] 
public class MyClass : IEnumerable<int>  
{ 
    [ProtoMember(1, IsPacked = true)] 
    public int[] data { get; set; } 

    // Comment out this indexed property to prevent the crash 
    public int this[int i] { get { return data[i]; } set { data[i] = value; } } 

    public IEnumerator<int> GetEnumerator() { foreach (var x in data) yield return x; } 
    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } 

    static void Main(string[] args) { Serializer.PrepareSerializer<MyClass>(); } 
} 

我做錯了什麼?我怎麼能告訴protobuf網序列化器忽略該索引器屬性?

謝謝!

編輯(10月10日):Marc已經通過[ProtoContract(IgnoreListHandling = true)]親切地提供了protobuf-net r447的修復。

+1

順便說一句; '[ProtoContract(IgnoreListHandling = true)]'會做到這一點; r447現在可供下載 –

回答

3

你的類型看起來像一個集合可疑,protobuf網真的試圖處理它。一個「修復」將是添加一個Add(int)方法,因爲是它想要在反序列化時使用的方法。不過,我正在調查爲什麼索引器的存在/缺失在這裏有所作爲(這對我來說並不是很明顯)。

請注意,因爲這看起來很像一個集合,[ProtoMember(...)]可能不會在這裏使用。直到我發現索引者在這裏玩什麼角色,我才100%確定。


Ahah; K表;發現索引器爲什麼涉及 - 實質上,在檢測到IEnumerable後,它試圖識別集合的Type;它採用各種線索:

  • <T>ICollection<T>
  • SomeTypeAdd(SomeType)
  • SomeTypepublic SomeTime this[int index] {...}索引
這些

,適用的是最後的唯一的一個。但是,IMO應該也可以使用<T>中的IEnumerable<T>(我可能會調整它) - 這至少會讓這種情況變得更加怪異(因爲會改善錯誤信息,我會這樣做)。總之,protobuf-net有許多非常特別的處理方式,用來處理像收藏品一樣的味道;個人而言,我會放棄IEnumerable<T>支持,並讓呼叫者通過.data代替;該消息將(在某些點)顯示:

無法解析爲{全名}合適的添加方法

+0

謝謝。真實世界類型實際上是一個ArraySegment 類的事物,顯示了底層數組的有限視圖。所以IEnumerable 的實現不會簡單地暴露數組。這些「線索」在TypeModel.ResolveListAdd()中,對嗎?我可能會嘗試破解一些... – Gabriel

+0

@Gabriel它是'GetListItemType',這裏有問題 –

+0

啊,是的,我現在明白了。謝謝! – Gabriel

相關問題