2011-12-11 98 views
2

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

重复数据(列表,收藏等)具有内置的行为,不能作为子类

调用堆栈跟踪

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 


} 
+0

我的心理调试器今天不工作;你能给我一个**提示**你的类型模型在这里的样子吗?例如,“InfoColumn ”是什么样的?它有什么基类型和派生类型?它实现了什么接口?它有一个'Add()'方法(这可能很重要)? –

+0

我已更新原始问题的课堂结构。感谢您的答复。 – GammaVega

+0

重新回答我的问题; r480已经上传到nuget和谷歌代码 –

回答

0

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

对v2中的类列表类型有更广泛的支持,它可能是它试图将上述解释为列表。确实,它看起来很像!我会试着去看看这种一般情况是否可以被检测和避免,但这是一个边缘情况(因为它确实非常流行)。

有一个现有的IgnoreListBehaviour开关,但是这验证了上面显示的模型时,似乎对于这种特定情况下的:“你不能这样做”禁用清单处理代码之前,火灾;我已经在源代码中改变了这一点,这将包含在下一个版本中。基本上,你可以通过添加解决这个问题:

[ProtoContract(IgnoreListHandling = true)] 

到受影响的类型(InfoColumn<T>),与下一个构建。这将是很快,一旦我完成验证等。

+0

感谢Marc快速转身。我拉起最新版本,添加上面的属性后,它确实修复了我的代码。 – GammaVega