Protobuf net protobuf net在使用索引属性时如何避免崩溃

Protobuf net protobuf net在使用索引属性时如何避免崩溃,protobuf-net,indexed-properties,Protobuf Net,Indexed Properties,我试图将这个很棒的protobuf网络集成到现有的代码库中,但是当它试图处理自定义类型时遇到了崩溃。下面是一个小演示:它将在ProtoBuf.Serializers.ListDecorator中抛出一个InvalidOperationException。但是,如果注释掉索引器(或删除IEnumerable实现),那么它将干净地运行 using System.Collections.Generic; using ProtoBuf; using System.Collections; [Proto

我试图将这个很棒的protobuf网络集成到现有的代码库中,但是当它试图处理自定义类型时遇到了崩溃。下面是一个小演示:它将在
ProtoBuf.Serializers.ListDecorator
中抛出一个
InvalidOperationException
。但是,如果注释掉索引器(或删除IEnumerable实现),那么它将干净地运行

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>(); }
}
使用System.Collections.Generic;
使用ProtoBuf;
使用系统集合;
[原始合同]
公共类MyClass:IEnumerable
{
[原成员(1,IsPacked=true)]
公共int[]数据{get;set;}
//注释掉此索引属性以防止崩溃
public int this[int i]{get{return data[i];}set{data[i]=value;}}
public IEnumerator GetEnumerator(){foreach(数据中的变量x)产生返回x;}
IEnumerator IEnumerable.GetEnumerator(){返回GetEnumerator();}
静态void Main(字符串[]args){Serializer.PrepareSerializer();}
}
我做错什么了吗?如何让protobuf网络序列化程序忽略该索引器属性

谢谢


编辑(10月10日):Marc已通过
[协议(IgnoreListHandling=true)]
提供了一个补丁

您的类型看起来可疑地像一个集合,protobuf net确实在尝试这样处理它。一个“修复”方法是添加一个
add(int)
方法,因为这是反序列化时要使用的方法。然而,我正在调查为什么索引器的存在/不存在会在这里产生影响(这对我来说不是很明显)

注意,因为这看起来非常像一个集合,所以这里可能不使用
[ProtoMember(…)]
。在我发现索引器在这里扮演什么角色之前,我不能100%确定


啊哈;K找到索引器参与的原因-本质上,在检测到
IEnumerable
后,它试图识别集合的
类型
;它使用各种线索:

  • i集合中的
  • Add(SomeType)
  • public中的
    SomeType
    可以使用此[int index]{…}
    索引器
其中,唯一适用的是最后一个。然而,在我看来,它可能还应该使用
IEnumerable
中的
(我可能会对此进行调整)-这至少会让这个场景不那么奇怪(我会改进错误消息)

总而言之,protobuf net对闻起来像收藏的东西有很多非常特殊的处理;就我个人而言,我会放弃对
IEnumerable
的支持,让调用方通过
.data
进行调用;消息将(在某个点)显示:

无法为{FullName}解析合适的Add方法


谢谢真实世界的类型实际上是一种ArraySegment类型的东西,显示底层数组的有限视图。因此IEnumerable的实现并不只是公开数组。这些“提示”在TypeModel.ResolveListAdd()中,对吗?我可能会尝试破解一下…@Gabriel这是
GetListItemType
的错啊,是的,我现在明白了。谢谢@Gabriel澄清一下,我在这里的首选选项是找出某种机制来表示“这实际上是一个单一对象;忽略所有列表处理”,而不是对该方法大惊小怪也许类似于
ProtoContractAttribute
中的
bool NotAList
属性<代码>[ProtoContract(IgnoreListHandling=true)]
将执行此操作;r447现在可供下载