2011-10-04 57 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

相关问题