我最近迁移到protobuf-net的新版本,之后我开始收到此错误消息

重复的数据(列表,集合等)具有内在行为,不能用作子类

调用堆栈跟踪

protobuf-net.dll!ProtoBuf.Meta.MetaType.AddSubType(int fieldNumber = 1, System.Type derivedType = {Name = "InfoColumn`1" FullName = "Om.Common.InfoSet.InfoColumn`1[[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}) Line 83    C#
protobuf-net.dll!ProtoBuf.Meta.MetaType.ApplyDefaultBehaviour() Line 431 + 0x32 bytes   C#

在这方面的任何帮助表示赞赏。 我打算将我的代码回滚到protobuf-net的先前版本

以下是课程信息。

[DataContract]
[ProtoInclude(1, typeof(InfoColumn<Double>))]
[ProtoInclude(2, typeof(InfoColumn<String>))]
[ProtoInclude(3, typeof(InfoColumn<DateTime>))]
[ProtoInclude(4, typeof(InfoColumn<Boolean>))]
public abstract class IInfoColumnBase 
{
    [DataMember(Order = 101)]
    public abstract bool IsSingleValue { get; set; }

    [DataMember(Order = 102)]
    public abstract string Name { get; set; }

    [DataMember(Order = 103)]
    public abstract InfoColumnDataType DataType { get; set; }
    public abstract long Insert();
    public abstract void Insert(long index);
    public abstract void SetValue(long index, object val);
    public abstract void CopyValues(long start, long end, IInfoColumnBase destCol, long index);
    public abstract long GetIndex(object val);
    public abstract void Remove(long index);
    public abstract object GetValue(long index);
    public abstract object GetInternalArrayValue(long index);
    public abstract void Clear();
    public abstract long Count { get; }
    public abstract long ArrayCount { get; }
}

public interface IInfoColumn<T>  : IEnumerable<T>
{
    T this[double index] { get; set; }
    InfoTable Table { get; set; }
    double Add(T item);
}


[DataContract(Name = "InfoColumn{0}")]
[KnownType(typeof(InfoColumn<double>))]
[KnownType(typeof(InfoColumn<String>))]
[KnownType(typeof(InfoColumn<bool>))]
[KnownType(typeof(InfoColumn<DateTime>))]
public class InfoColumn<T> : IInfoColumnBase, IInfoColumn<T> 
{
    long counter = 0;
    [DataMember(Order = 1)]
    public IList<T> Values { get; set; }

    //[DataMember(Order = 2)]
    bool isSingleVal = false;

    //[DataMember(Order=3)]
    public override string Name { get; set; }

    //[DataMember(Order=4)]
    public override InfoColumnDataType DataType { get; set; }

    public InfoTable Table { get; set; }


    public override long Count
    {
        get
        {
            return this.Table.Count;
        }
    }

    public override long ArrayCount
    {
        get { return this.Values.Count; } 
    }

    public InfoColumn()
    {
    }

    public InfoColumn(string name,InfoTable table)
    {
        this.Values = new List<T>();
        this.Name = name;
        this.Table = table;
    }

    public override void Clear()
    {
        this.Values = new List<T>();
    }

    public override void Remove(long index)
    {
        int newindex = (int)index;
        this.Values.RemoveAt(newindex);

    }



    public override void CopyValues(long start, long end, IInfoColumnBase destCol, long startIndex)
    {
        InfoColumn<T> typeCol = destCol as InfoColumn<T>;
        for (long ctr = start; ctr <= end; ctr++)
        {
            typeCol.SetValue(startIndex, this.Values[(int)ctr]);
            startIndex++;
        }
    }

    public override void Insert(long rows)
    {

        if (this.IsSingleValue == true) return;

        for (int ctr = 0; ctr < rows; ctr++)
        {
            this.Values.Add(default(T));
        }
    }

    public  T this[double a]
    {
        get
        {
            if (a >= this.Count) throw new IndexOutOfRangeException();
            long index = (long)a;
            if (this.Table.IsFreezed == false)
                index = this.Table.CheckData(a);


            if (this.isSingleVal == true)
                return this.Values[0];
            else 
                return this.Values[(int)index];
        }
        set
        {
            if (a >= this.Count) throw new IndexOutOfRangeException();

            long index = (long)a; 

            if (this.Table.IsFreezed == false)
                index = this.Table.CheckData(a);

            if (this.isSingleVal == true)
                this.Values[0] = value;
            else
                this.Values[(int)index] = value;

        }
    }

    public override long GetIndex(object val)
    {
        T item = (T)val;
        return this.Values.IndexOf(item);
    }

    public override void SetValue(long index, object val)
    {
        if (val is InfoSetLink)
            this.Values[(int)index] = (T)val;
        else
            this.Values[(int)index] = (T)Convert.ChangeType(val, typeof(T));
    }

    public override object GetValue(long index)
    {
        return this[index];
    }

    public override object GetInternalArrayValue(long index)
    {
        return this.Values[(int)index];
    }


    //[DataMember(Order=5)]
    public override bool IsSingleValue 
    {
        get { return isSingleVal; }
        set
        {
            if (isSingleVal == true)
            {
                this.Values = new List<T>(1);
            }
        }
    }

    public override long Insert()
    {
        if (this.IsSingleValue == true) return -1;
        this.Values.Add(default(T));
        return this.Values.Count - 1;
    }

    public double Add(T item)
    {
        this.Values.Add(item);
        return this.Values.Count - 1;
    }

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator()
    {
        return new InfoColumnEnumerator<T>(this);
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return new InfoColumnEnumerator<T>(this);
    }

    #endregion


}

===============>>#1 票数:0 已采纳

InfoColumn<T>具有公共Add(T)并实现IEnumerable<T> (通过IInfoColumn<T> )。

v2中对类似列表的类型提供了更广泛的支持,可能是它试图将以上内容解释为列表。 实际上,它确实看起来很像! 我将尝试看一下是否可以检测到并避免这种一般情况,但这是一个极端的情况(因为它确实非常像列表一样)。

有一个现有的IgnoreListBehaviour开关,但是在验证上面显示的模型时,似乎对于这种特定情况 ,在禁用列表处理的代码之前会触发“您不能执行此操作”。 我已经在源代码中对此进行了更改,并将在下一个版本中包含。 基本上,您可以通过添加以下内容来解决此问题:

[ProtoContract(IgnoreListHandling = true)]

转换为受影响的类型( InfoColumn<T> ),并进行下一个构建。 等我完成验证等后不久。

  ask by GammaVega translate from so

未解决问题?本站智能推荐:

1回复

如何从WCF DatacontractSerializer正确迁移到Protobuf-net?

我们有很多类的庞大应用程序。 我们目前正在使用Monotouch将此.net应用程序移植到IPad。 我们在使用DataContractSerializer时遇到了一些问题,我们想使用Marc Gravell的protobuf-net序列化器。 客户端和服务器之间的通信由WCF服务管理
2回复

protobuf-net,版本控制和代理类型的最佳实践

我正在尝试确定如何使用protobuf-net(Marc Gravell的实现)解决此用例。 我们有A类,被认为是版本1 类A的实例已序列化到磁盘 现在,我们有了类B,它被视为类A的版本2(类A有太多错误,我们必须为下一个版本创建类B)。 类A仍然存在于代码中,但仅出
1回复

Protobuf的问题

我切换到另一台计算机上工作,安装了Visual C#express和protoBuf-net,然后将项目源复制到另一台计算机上。 现在,当我在第二台计算机上打开项目时,该程序不会对数据进行序列化和反序列化。 调试时,每次使用Protobuf进入一段代码时,都会收到以下消息:
1回复

如何使用protobuf-net将成员安全地转移到基层

我有一个使用protobuf-net进行序列化的数据合同。 上一次决定重构它们并将某些属性移至基类的决定,例如: 此后,我发现属性Friends没有从以前的序列化数据中反序列化。 我如何在不中断更改的情况下执行这样的重构?
1回复

Protobuf-net枚举序列化行为在版本中发生了变化。 2.3.0

2.3.0之前的任何序列化对象如果包含枚举值并且使用DataMember和InferTagFromNameDefault而不是ProtoMember,则无法在2.3.0或更高版本中正确反序列化。 我有这门课。 使用此代码对其进行序列化。 在2.3.0之前,这将导致字节[] {8
1回复

版本控制Protobuf-net序列化的C#对象

我已经使用protobuf-net序列化了C#类。 结果字节数组存储在数据库中。 这是出于性能原因,我可能将无法更改此设计。 C#语言无法阻止修改类,并且随着时间的推移反序列化所传递的类结构可能需要与序列化不匹配的更改,从而导致检索失败。 除了这里建议的包装技术之外,是否有用于解决此
1回复

ProtoBuf,继承和泛型

给出以下代码: 尝试序列化ContainerA / ContainerB时出现错误: ProtoBuf.ProtoException:ProtoIncludeAttribute的已知类型ContainerB必须是Container`1的直接子类 注释掉以下几行之一-以便
1回复

protobuf-net是否支持protobuf扩展?

我有一个base.proto,其中包含一组可以使用protobuff扩展名扩展的消息,然后我有一个comm.proto,它扩展了base.proto中定义的某些消息。 我使用ProtoGen生成了base.cs和comm.cs文件,但无法访问comm.cs添加的扩展名字段。 是否支持
2回复

用protobuf替换binaryformatter

我需要替换一个将数据存储在文件中的库(序列化/反序列化),该库当前使用BinaryFormatter来实现,但是对于大型列表而言它的速度很慢。 关于stackoverflow的许多帖子都表明protobuf确实很出色,所以我正在尝试使用它。 为了在不重写大量代码的情况下进行替换,我的要求
1回复

Protobuf继承和泛型

我试图使用ProtoBuf net来序列化具有以下格式的类的对象树: 注意我序列化的类( MySpecialCollectionList<T> )是如何从List<SomeOtherClass<T>>派生的,而不仅仅是List<T> 。